vir*_*ent 7 mysql innodb replication performance
我有两个经常更新的表,一个是直接的UPDATE ..
,另一个是直接的,INSERT .. ON DUPLICATE KEY UPDATE ...
通常这些查询是即时的,但有时需要 0.1 秒到 1+ 秒,然后又是即时的几秒钟。
另一件事要注意,我有两个 MySQL 服务器(在同一个专用网络中)。所有选择查询(除了一两个)都在从站上执行,这里看到的插入当然在主站上。当数据库处于大负载下时,速度减慢最为明显。最后,我正在使用 xtradb(看看它是否有帮助),但在纯 MySQL 5.5 InnoDB 上发生了相同的行为。
-- CustomData
+-----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| Server | int(11) | NO | PRI | NULL | |
| Plugin | int(11) | NO | PRI | NULL | |
| ColumnID | int(11) | NO | PRI | NULL | |
| DataPoint | int(11) | NO | | NULL | |
| Updated | int(11) | NO | MUL | NULL | |
+-----------+---------+------+-----+---------+-------+
Run Code Online (Sandbox Code Playgroud)
前任。几个查询:
mysql> insert into CustomData (Server, Plugin, ColumnID, DataPoint, Updated) VALUES ( 52707, 1, 1, 0, 1327093596) on duplicate key update DataPoint = 0 , Updated = 1327093596 ;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into CustomData (Server, Plugin, ColumnID, DataPoint, Updated) VALUES ( 52707, 1, 1, 0, 1327093596) on duplicate key update DataPoint = 0 , Updated = 1327093596 ;
Query OK, 0 rows affected (0.12 sec)
mysql> insert into CustomData (Server, Plugin, ColumnID, DataPoint, Updated) VALUES ( 52707, 1, 1, 0, 1327093596) on duplicate key update DataPoint = 0 , Updated = 1327093596 ;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into CustomData (Server, Plugin, ColumnID, DataPoint, Updated) VALUES ( 52707, 1, 1, 0, 1327093596) on duplicate key update DataPoint = 0 , Updated = 1327093596 ;
Query OK, 0 rows affected (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
解释-
mysql> explain select * from CustomData where Server = 52707 and Plugin = 1 and ColumnID = 1 ;
+----+-------------+------------+-------+---------------+---------+---------+-------------------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+---------+---------+-------------------+------+-------+
| 1 | SIMPLE | CustomData | const | PRIMARY,Cron | PRIMARY | 12 | const,const,const | 1 | |
+----+-------------+------------+-------+---------------+---------+---------+-------------------+------+-------+
Run Code Online (Sandbox Code Playgroud)
探查器(用于 0.12 秒查询)
mysql> show profile for query 56 ;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000062 |
| checking permissions | 0.000005 |
| Opening tables | 0.000016 |
| System lock | 0.000007 |
| init | 0.000011 |
| update | 0.129531 |
| end | 0.000005 |
| query end | 0.000012 |
| closing tables | 0.000008 |
| freeing items | 0.000017 |
| logging slow query | 0.000001 |
| cleaning up | 0.000036 |
+----------------------+----------+
Run Code Online (Sandbox Code Playgroud)
所有其他有问题的查询都非常相似。我没有注意到任何长时间运行的查询show processlist;
显示引擎 INNODB 状态(需要 10 个代表才能发布 >2 个链接,所以)- pastebin .com/raw.php?i=tdtZeTCJ
我要注意的最后一件事是,在给定的示例中,任何工作人员都只会INSERT .. ON DUPLICATE KEY
在唯一的行上执行,而不是在同一行上(因此每个查询都针对不同的行)
提前致谢!
编辑:
我所有的数据都在 3G 左右,带有索引。缓冲池大小最初是 2G,但也尝试过 4G。
我的.cnf-
[mysqld]
datadir = /data/mysql
socket = /var/run/mysqld/mysqld.sock
user = mysql
bind-address = 10.10.1.7
log-slow-queries = mysql-slow.log
long_query_time = 5
log-queries-not-using-indexes
# Replication
server-id = 1
# master
log-bin = /var/log/mysql/mysql-bin.log
expire-logs-days = 10
binlog-do-db = metrics
max_binlog_size = 104857600
binlog_format = MIXED
# slave
# replicate-do-db = metrics
# read_only = 1
# /Replication
skip-external-locking
sysdate-is-now
performance_schema
log-error=/var/log/mysql.log
default-storage-engine = InnoDB
innodb_file_per_table = 1
innodb_file_format = barracuda
innodb_buffer_pool_size = 4G
innodb_additional_mem_pool_size = 10M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 0
innodb_lock_wait_timeout = 50
innodb_fast_shutdown = 1
innodb_flush_method = O_DIRECT
transaction_isolation = READ-COMMITTED
max_connections = 4092
connect_timeout = 86400
wait_timeout = 86400
interactive_timeout = 86400
max_allowed_packet = 64M
open_files_limit = 2048
table_cache = 2048
net_buffer_length = 8K
query_cache_type = 1
query_cache_size = 16M
thread_cache = 100
thread_stack = 512K
tmpdir = /dev/shm
tmp_table_size = 64M
key_buffer_size = 64M
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
Run Code Online (Sandbox Code Playgroud)
编辑2
innotop-
我读到了间隙锁定 - 是否有可能是间隙锁定我的Plugin
和ColumnID
列,忽略了 PK 是 3 列的事实以及我使用的是 READ-COMMITTED 所以它不应该是这样的事实?正如在 innotop 中看到的,有些是非常接近的,所以如果是这种情况,那么就会有很多锁
mysql> show indexes from CustomData;
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| CustomData | 0 | PRIMARY | 1 | Server | A | 1073724 | NULL | NULL | | BTREE | | |
| CustomData | 0 | PRIMARY | 2 | Plugin | A | 1879017 | NULL | NULL | | BTREE | | |
| CustomData | 0 | PRIMARY | 3 | ColumnID | A | 7516069 | NULL | NULL | | BTREE | | |
| CustomData | 1 | Cron | 1 | Plugin | A | 20 | NULL | NULL | | BTREE | | |
| CustomData | 1 | Cron | 2 | ColumnID | A | 20 | NULL | NULL | | BTREE | | |
| CustomData | 1 | Cron | 3 | Updated | A | 7516069 | NULL | NULL | | BTREE | | |
| CustomData | 1 | Updated | 1 | Updated | A | 2505356 | NULL | NULL | | BTREE | | |
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
Run Code Online (Sandbox Code Playgroud)
cron 键每 30 分钟只使用一次,现在甚至没有启用(以防它被调出)
您需要对 InnoDB 设置进行一些调整
由于我没有看到innodb_log_file_size,我假设你有默认的5M。由于你的 innodb_buffer_pool_size = 是 4G,所以你需要 1G 重做日志。
InnoDB 开箱即用,并不使用所有 CPU。我很久以前写过一篇关于 InnoDB LEFT UNCONFIGURED 如何在旧版本中运行得更快的文章。我还写了关于 InnoDB 多核参与的文章:
说了这么多,以下是要做的调整
cp /etc/my.cnf /etc/my.cnf_old
Run Code Online (Sandbox Code Playgroud)
将此设置添加到 /etc/my.cnf
[mysqld]
innodb_log_file_size = 1G
innodb_io_capacity = 20000
innodb_read_io_threads = 5000
innodb_write_io_threads = 5000
Run Code Online (Sandbox Code Playgroud)
接下来,运行这些步骤
service mysql stop
mv /var/log/mysql/ib_logfile0 /var/log/mysql/ib_logfile0_old
mv /var/log/mysql/ib_logfile1 /var/log/mysql/ib_logfile1_old
service mysql start
Run Code Online (Sandbox Code Playgroud)
现在,所有核心都支持InnoDB,并且有更多的事务隔离空间
试一试 !!!