【整理】MySQL 之 autocommit
生活随笔
收集整理的這篇文章主要介紹了
【整理】MySQL 之 autocommit
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2019獨角獸企業重金招聘Python工程師標準>>>
mysql 默認是開啟 auto commit 的??梢酝ㄟ^如下命令查看 session 級別和 global 級別的設置:
mysql> select @@session.autocommit; +----------------------+ | @@session.autocommit | +----------------------+ | 1 | +----------------------+ 1 row in set (0.00 sec)mysql> select @@global.autocommit; +---------------------+ | @@global.autocommit | +---------------------+ | 1 | +---------------------+ 1 row in set (0.00 sec)mysql> ? ? ?? 那么如果我們不想讓 mysql 執行自動提交時,應該如何禁用 autocommit 呢?可以通過 Cmd-Line、Option file、System Var 上都可用的 init_connect 來設置。
A string to be executed by the server for each client that connects. The string consists of one or more SQL statements. To specify multiple statements, separate them by semicolon characters. ? ? ?? 上面這段話的意思是,每個 client 連接上來時都會由 server 執行一次由 init_connect 指定的 sql 字串。(是否可以認為是基于 session 的?)
利用這個變量,可以通過如下方式禁用 autocommit:
方法一:
mysql>SET GLOBAL init_connect='SET autocommit=0'; 方法二:
在 MySQL 的配置文件中設置
[mysqld] init_connect='SET autocommit=0' 方法三:
啟動 mysql 時帶上命令行參數 –init_connect='SET autocommit=0'
值得說明的一點是,這個參數的設置對擁有 super 權限的用戶是無效的,具體原因說明如下:
Note that the content of init_connect is not executed for users that have the SUPER privilege. This is done so that an erroneous value for init_connect does not prevent all clients from connecting. For example, the value might contain a statement that has a syntax error, thus causing client connections to fail. Not executing init_connect for users that have the SUPER privilege enables them to open a connection and fix the init_connect value. ? ? ?? 默認開啟的 autocommit 肯定會對 mysql 的性能有一定影響,但既然默認開啟必定是有原因的,所以如果你不知道自己到底會遇到什么問題的情況下還是不要改這個設置為妙。舉個例子來說明開啟 autocommit 會產生的性能影響,如果你插入了 1000 條數據,mysql 會 commit 1000 次,如果我們把 autocommit 關閉掉,通過程序來控制,只要一次commit 就可以了。
========= 我是分割線? =========
? ? ? 另外一篇博客《Innodb表類型中autocommit的設置》中展示了設置 autocommit 為 0 的效果。
a. 初始狀態+設置 session 級別的 autocommit 為 0
mysql> mysql> show binlog events; +------------------+-----+-------------+-----------+-------------+---------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+-------------+-----------+-------------+---------------------------------------+ | mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.10-log, Binlog ver: 4 | +------------------+-----+-------------+-----------+-------------+---------------------------------------+ 1 row in set (0.00 sec)mysql> mysql> show tables; Empty set (0.00 sec)mysql> mysql> select @@global.autocommit; +---------------------+ | @@global.autocommit | +---------------------+ | 1 | +---------------------+ 1 row in set (0.00 sec)mysql> select @@session.autocommit; +----------------------+ | @@session.autocommit | +----------------------+ | 1 | +----------------------+ 1 row in set (0.00 sec)mysql> mysql> set autocommit=0; Query OK, 0 rows affected (0.00 sec)mysql> mysql> select @@global.autocommit; +---------------------+ | @@global.autocommit | +---------------------+ | 1 | +---------------------+ 1 row in set (0.00 sec)mysql> select @@session.autocommit; +----------------------+ | @@session.autocommit | +----------------------+ | 0 | +----------------------+ 1 row in set (0.00 sec)mysql> b. 創建一個測試表
mysql> create table t_autocommit(-> id int not null auto_increment,-> amount int not null default '0',-> primary key(id)-> )engine=innodb; Query OK, 0 rows affected (0.01 sec)mysql> mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | t_autocommit | +----------------+ 1 row in set (0.00 sec)mysql> mysql> describe t_autocommit; +--------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | amount | int(11) | NO | | 0 | | +--------+---------+------+-----+---------+----------------+ 2 rows in set (0.00 sec)mysql> mysql> select * from t_autocommit; Empty set (0.00 sec)mysql> c. 插入數據
mysql> mysql> insert into t_autocommit set amount=1; Query OK, 1 row affected (0.00 sec)mysql> mysql> select * from t_autocommit; +----+--------+ | id | amount | +----+--------+ | 1 | 1 | +----+--------+ 1 row in set (0.00 sec)mysql> mysql> update t_autocommit set amount=amount+10; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0mysql> mysql> select * from t_autocommit; +----+--------+ | id | amount | +----+--------+ | 1 | 11 | +----+--------+ 1 row in set (0.00 sec)mysql> mysql> show binlog events; +------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+ | mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.10-log, Binlog ver: 4 | | mysql-bin.000001 | 120 | Query | 1 | 316 | use `test`; create table t_autocommit( id int not null auto_increment, amount int not null default '0', primary key(id) )engine=innodb | +------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec)mysql> ? ? ?? 發現 binlog 中僅記錄了 create table 動作,insert 和 update 由于 autocommit 為 0 的緣故沒有被記錄到 binlog 中。
d.斷開 mysql ,再重新連接。
mysql> mysql> quit Bye [root@Betty ~]# [root@Betty ~]# mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.6.10-log Source distributionCopyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -ADatabase changed mysql> mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | t_autocommit | +----------------+ 1 row in set (0.00 sec)mysql> mysql> select * from t_autocommit; Empty set (0.00 sec)mysql> ? ? ?? 發現什么數據都沒有。為什么呢?因為 SQL 語句并沒有被自己(當前 session)提交給 server 端去處理,只是在當前連接中做了相應處理。
重復上面的實驗,但是保持 autocommit 的默認值(1)。
mysql> mysql> show binlog events; +------------------+-----+-------------+-----------+-------------+---------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+-------------+-----------+-------------+---------------------------------------+ | mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.10-log, Binlog ver: 4 | +------------------+-----+-------------+-----------+-------------+---------------------------------------+ 1 row in set (0.00 sec)mysql> mysql> show tables; Empty set (0.01 sec)mysql> mysql> select @@global.autocommit; +---------------------+ | @@global.autocommit | +---------------------+ | 1 | +---------------------+ 1 row in set (0.00 sec)mysql> mysql> select @@session.autocommit; +----------------------+ | @@session.autocommit | +----------------------+ | 1 | +----------------------+ 1 row in set (0.00 sec)mysql> mysql> create table t_autocommit(-> id int not null auto_increment,-> amount int not null default '0',-> primary key(id)-> )engine=innodb; Query OK, 0 rows affected (0.01 sec)mysql> mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | t_autocommit | +----------------+ 1 row in set (0.00 sec)mysql> mysql> describe t_autocommit; +--------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | amount | int(11) | NO | | 0 | | +--------+---------+------+-----+---------+----------------+ 2 rows in set (0.00 sec)mysql> mysql> insert into t_autocommit set amount=1; Query OK, 1 row affected (0.00 sec)mysql> mysql> select * from t_autocommit; +----+--------+ | id | amount | +----+--------+ | 1 | 1 | +----+--------+ 1 row in set (0.00 sec)mysql> mysql> update t_autocommit set amount=amount+10; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0mysql> mysql> select * from t_autocommit; +----+--------+ | id | amount | +----+--------+ | 1 | 11 | +----+--------+ 1 row in set (0.00 sec)mysql> mysql> show binlog events; +------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+ | mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.10-log, Binlog ver: 4 | | mysql-bin.000001 | 120 | Query | 1 | 316 | use `test`; create table t_autocommit( id int not null auto_increment, amount int not null default '0', primary key(id) )engine=innodb | | mysql-bin.000001 | 316 | Query | 1 | 395 | BEGIN | | mysql-bin.000001 | 395 | Intvar | 1 | 427 | INSERT_ID=1 | | mysql-bin.000001 | 427 | Query | 1 | 538 | use `test`; insert into t_autocommit set amount=1 | | mysql-bin.000001 | 538 | Xid | 1 | 569 | COMMIT /* xid=62 */ | | mysql-bin.000001 | 569 | Query | 1 | 648 | BEGIN | | mysql-bin.000001 | 648 | Query | 1 | 762 | use `test`; update t_autocommit set amount=amount+10 | | mysql-bin.000001 | 762 | Xid | 1 | 793 | COMMIT /* xid=64 */ | +------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+ 9 rows in set (0.00 sec)mysql> mysql> quit Bye [root@Betty ~]# [root@Betty ~]# mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.6.10-log Source distributionCopyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -ADatabase changed mysql> mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | t_autocommit | +----------------+ 1 row in set (0.00 sec)mysql> mysql> select * from t_autocommit; +----+--------+ | id | amount | +----+--------+ | 1 | 11 | +----+--------+ 1 row in set (0.00 sec)mysql> mysql> 這回該有的都有了。
========= 我是分割線? =========
網友說法:
不要設定 autocommit 這個開關,讓它保持 autocommit=1 這個默認狀態。 平常有查詢\更新都是需要得到最新的數據,根本不需要啟動一個事務,除非有特定狀況才需要開啟事務,再手工用 start transaction ... commit /rollback 。 這種全局設置,在生產環境中沒有多大意義。一般都是在應用程序框架(如連接池的庫)中設置 autocommit 是否為 ON/OFF, 說白了,就是得到數據庫連接以后,顯示的調用一次 set autocommit on/off (or =1/0)
轉載于:https://my.oschina.net/moooofly/blog/169824
總結
以上是生活随笔為你收集整理的【整理】MySQL 之 autocommit的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue跨域解决方案websocket_前
- 下一篇: 使用的 SQL Server 版本不支持