0%

需求

服务器意外断电,导致mysql启动不了

强制恢复后备份

进入恢复模式

在 /etc/my.cnf中添加如下配置:

1
2
[mysqld]
innodb_force_recovery = 1

其中后面的值设置为1、如果1不能启动成功,再逐步增加为2/3/4/5/6等。直到能启动mysql为止!!!

需求

由于某些原因,数据库表中出现了一下重复数据

查询重复数据

1
select * from member where mobile in (select mobile from member group by mobile having count(*)>1);

删除其他重复记录保留最新一条

1
delete from member where id not in (select t.max_id from (select max(id) as max_id from member group by mobile having count(*)>1) as t);

需求

  • 玩Linux,经常需要重装系统,所以我的文件都是放 /data 目录下,data 目录是一个独立的分区,每次重装系统时只需要重新挂载分区到 /data 目录即可,非常方便。配合 konsave 工具和软件安装脚本,基本上十多分钟就可以恢复系统原样。对 data 目录的备份至关重要。
  • 工作时经常需要在生产环境进行软件部署,有时可能只改了几个文件,也需要重新上传全量包到生产环境,其实完全没必要,更新修改的文件即可。

rsync的优点

  • 会检查发送方和接收方已有的文件,仅传输有变动的部分
  • 支持断点续传,可替代sftp使用

rsync使用( 参考 )

1
rsync -avzc --delete --partial --append-verify --progress -e "ssh -p 22" /xxx/xxx root@x.x.x.x:/yyy/yyy
  • -a 表示存档模式,保存所有的元数据,比如修改时间(modification time)、权限、所有者等
  • -v 表示输出细节。=-vv=表示输出更详细的信息,=-vvv=表示输出最详细的信息。
  • -z 表示指定同步时压缩数据
  • -c 默认情况下,rsync 只检查文件的大小和最后修改日期是否发生变化,如果发生变化,就重新传输;使用这个参数以后,则通过判断文件内容的校验和,决定是否重新传输。
  • --delete 删除目标目录下的多余文件,使得目标目录成为源目录的镜像副本
  • --partila 表示允许恢复中断的传输
  • --append-verify 表示接着上次中断的地方继续传输,并对传输完成后的文件进行一次校验。如果校验失败,将重新发送整个文件。
  • --progress 表示显示进展
  • -e 指定使用 SSH 协议传输数据

异常一

dockerd 启动提示:(docker0): networks have same bridge name

原因分析

使用 docker-compose 的方式部署时,默认的网络模式是bridge , 默认网段是172.17.0.1/16,即docker0。自动生成的网桥会依次使用:172.18.x.x ,172.19.x.x…. 这些docker生成的网段可能与内网网段有冲突。

问题

echarts热力图渲染数据超过2万会感觉明显卡顿

解决办法

后端通过网格将数据聚合,压缩数据量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// 网格聚合核心方法
public static JSONArray gridAggregate(JSONArray points, int xGridSize, int yGridSize) throws JSONException {

    if(points.size() <= 20000){
        return points;
    }

    // 1. 计算坐标范围
    double minX = 0, maxX = 0, minY = 0, maxY = 0;

    for (int i = 0; i < points.size(); i++) {
        JSONArray point = points.getJSONArray(i);
        double x = point.getDouble(0);
        double y = point.getDouble(1);
        if(i == 0){
            minX = x;
            maxX = x;
            minY = y;
            maxY = y;
        }else{
            minX = Math.min(minX, x);
            maxX = Math.max(maxX, x);
            minY = Math.min(minY, y);
            maxY = Math.max(maxY, y);
        }
    }

    // 2. 初始化网格容器 (使用网格坐标作为Key)
    TreeMap<String, List<Double>> gridMap = new TreeMap<>();
    double gridWidth = (maxX - minX) / xGridSize;
    double gridHeight = (maxY - minY) / yGridSize;

    // 3. 点分配到网格
    for (int i = 0; i < points.size(); i++) {
        JSONArray point = points.getJSONArray(i);
        double x = point.getDouble(0);
        double y = point.getDouble(1);
        double value = point.getDouble(2);

        int gridX = (int) ((x - minX) / gridWidth);
        int gridY = (int) ((y - minY) / gridHeight);
        String gridKey = gridX + "_" + gridY;

        gridMap.computeIfAbsent(gridKey, k -> new ArrayList<>()).add(value);
    }

    // 4. 生成聚合数据 (使用平均值策略)
    JSONArray aggregatedData = new JSONArray();
    for (Map.Entry<String, List<Double>> entry : gridMap.entrySet()) {
        String[] keys = entry.getKey().split("_");
        int gridX = Integer.parseInt(keys[0]);
        int gridY = Integer.parseInt(keys[1]);

        // 计算网格中心坐标
        double centerX = minX + (gridX + 0.5) * gridWidth;
        double centerY = minY + (gridY + 0.5) * gridHeight;

        // 计算平均值
        double avgValue = entry.getValue().stream()
                .mapToDouble(Double::doubleValue)
                .average()
                .orElse(0.0);

        // 构建新数据点 [x, y, value]
        JSONArray newPoint = new JSONArray();
        newPoint.put(new BigDecimal(centerX).setScale(2, RoundingMode.DOWN).intValue());
        newPoint.put(new BigDecimal(centerY).setScale(2, RoundingMode.DOWN).doubleValue());
        newPoint.put(new BigDecimal(avgValue).setScale(6, RoundingMode.DOWN).doubleValue());

        aggregatedData.put(newPoint);
    }

    //System.out.println("原始点数: " + points.size());
    //System.out.println("聚合后点数: " + aggregatedData.size());

    aggregatedData.sort((o1, o2) -> {
        JSONArray points1 = (JSONArray) o1;
        JSONArray points2 = (JSONArray) o2;
        return points1.getInt(0).compareTo(points2.getInt(0));
    });

    return aggregatedData;
}

方法一:用官方迁移工具KDTS

同事告知,用KDTS,从mysql迁移到人大金仓数据库没问题。但从人大金仓数据库迁移到mysql会失败,原因未明。 KDTS工具为安装人大金仓数据库自带,没有独立版本。 docker版本的人大金仓数据库没有此公具。

需求

之前一直用 docker logs -f 容器ID 查看日志,遇到一个问题,一旦打印的日志太多,好像是从上一次查看的位置开始输出,导致终端在狂刷日志,而我只想看最新的日志。

需求

在特定场景下,可能只需要修改jar包里的某个配置或替换某个class文件。

jar包解压

1
2
3
4
5
6
# 方法一(推荐)使用 unzip 解压到指定目录
unzip xxx.jar -d 指定解压路径
# 方法二使用 jar 解压(只能解压到当前目录)
mkdir	xxx
cd xxx
jar -xvf xxx.jar

jar包压缩

1
2
# 使用 jar 压缩当前目录(压缩指定目录会把文件夹也一起压缩)
jar -cfM /xxx/xxx.jar	.

使用Dconf Editor

打开Dconf Editor,导航到 org -> gnome -> desktop -> break-reminders,然后选择 eyesight 或 movement(分别对应短时间休息和长时间休息)。在该路径下,可以设置 interval-seconds 来调整休息时间间隔