开发哥们最近遇到个问题,说是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