MySQL在非双1场景下的丢数据问题

2023-09-04 18:14:43 浏览数 (2)

开发哥们最近遇到个问题,说是Django ORM日志上看数据已经提交了,但是服务器突然断电,重启后发现之前写入的数据丢失了。 让我帮看看什么原因导致的。

这个问题其实很常见,大概率是MySQL没有设置双一导致的。

下面简单实验模拟下。

代码语言:javascript复制
先确保mysqld单进程运行
(如果是mysqld_safe守护的请先kill掉mysqld_safe进程,防止我们后面kill -9的时候,mysqld会自动再次拉起mysqld进程)
(systemd守护的也会自动拉起)

代码语言:javascript复制
设置下参数,确保非双1

# 我这里是修改后的参数
mysql [localhost:5726] {root} ((none)) > show global variables like '%innodb%trx%commit%';
 -------------------------------- ------- 
| Variable_name                  | Value |
 -------------------------------- ------- 
| innodb_flush_log_at_trx_commit | 0     |
 -------------------------------- ------- 
1 row in set (0.00 sec)

mysql [localhost:5726] {root} ((none)) > show global variables like '%sync%bin%';
 --------------- ------- 
| Variable_name | Value |
 --------------- ------- 
| sync_binlog   | 0     |
 --------------- ------- 
1 row in set (0.01 sec)

代码语言:javascript复制
# 当前数据库里面情况
mysql [localhost:5726] {root} ((none)) > select * from test.t1;
 ---- ------ ------ 
| id | name | sex  |
 ---- ------ ------ 
|  1 | wang | M    |
|  2 | wang | F    |
 ---- ------ ------ 
2 rows in set (0.00 sec)

脚本模拟:

代码语言:javascript复制

# a.sh脚本
# 先写入数据,然后查出来,最近kill -9 杀进程
mysql -S /tmp/mysql_sandbox5726.sock -uroot -pmsandbox -e 'update test.t1 set sex="A" where id=2'
mysql -S /tmp/mysql_sandbox5726.sock -uroot -pmsandbox -e 'select * from  test.t1 where id=2'
kill -9 28048  # 直接kill mysqld进程,这里的进程号替换成自己机器上的

脚本执行过程如下:
$ sh a.sh
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql: [Warning] Using a password on the command line interface can be insecure.
 ---- ------ ------ 
| id | name | sex  |
 ---- ------ ------ 
|  2 | wang | A    |
 ---- ------ ------ 

再次启动mysqld,查看数据更新情况

代码语言:javascript复制

./start 

$ mysql -S /tmp/mysql_sandbox5726.sock -uroot -pmsandbox -e 'select * from  test.t1 where id=2'
mysql: [Warning] Using a password on the command line interface can be insecure.
 ---- ------ ------ 
| id | name | sex  |
 ---- ------ ------ 
|  2 | wang | F    |  # 可以看到数据没有更新成功,还是F
 ---- ------ ------ 

代码语言:javascript复制
至此,我们也看到了如果MYSQL参数设置非双1是极其危险的。

生产上主节点切记请设置为双一,从库一般可以宽松点,例如设置为: 
sync_binlog=100
innodb_flush_log_at_trx_commit=2

0 人点赞