Mysql

非常差的插入性能 MySQL / Percona Server

  • April 7, 2021

我在 Ubuntu 伺服器安裝中執行 Percona-Server 實例。我正在使用一個需要訪問該數據庫的應用程序,並且它的性能非常差。建立數據庫後,應用程序進入(安裝時)並創建模式。它將所有內容預設為 MyISAM,但是我已將表引擎轉換回 InnoDB。我遇到的問題是插入性能非常差。該應用程序的寫入量很大,似乎每次將每行 1 寫入磁碟,不使用任何類型的緩衝區,但是我不確定如何檢查或驗證這一點。即使從其中一個表中選擇(*)也需要 2.4 秒,並且只有 163,000 行。我有點不知所措,我還能做什麼。

伺服器有 8GB 的​​記憶體,在這種情況發生時 CPU 幾乎完全空閒。

我的.cnf:

[mysql]

# CLIENT #
port                           = 3306
socket                         = /var/run/mysqld/mysqld.sock

[mysqld]

# GENERAL #
user                           = mysql
default_storage_engine         = InnoDB
socket                         = /var/run/mysqld/mysqld.sock
pid_file                       = /var/run/mysqld/mysqld.pid

# MyISAM #
key_buffer_size                = 32M
myisam_recover                 = FORCE,BACKUP

# SAFETY #
max_allowed_packet             = 16M
max_connect_errors             = 1000000
skip_name_resolve
sql_mode                       = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ONLY_FULL_GROUP_BY
sysdate_is_now                 = 1
innodb                         = FORCE
innodb_strict_mode             = 1

# DATA STORAGE #
datadir                        = /mnt/Storage/mysql/

# BINARY LOGGING #
log_bin                        = /mnt/Storage/mysql/mysql-bin
expire_logs_days               = 14
sync_binlog                    = 1

# CACHES AND LIMITS #
tmp_table_size                 = 32M
max_heap_table_size            = 32M
query_cache_type               = 0
query_cache_size               = 0
max_connections                = 500
thread_cache_size              = 50
open_files_limit               = 65535
table_definition_cache         = 1024
table_open_cache               = 2048

# INNODB #
innodb_flush_method            = O_DIRECT
innodb_log_files_in_group      = 2
innodb_log_file_size           = 512M
innodb_flush_log_at_trx_commit = 0
innodb_file_per_table          = 1
innodb_buffer_pool_size        = 6144M
innodb_buffer_pool_instances   = 1
innodb_read_io_threads         = 64
innodb_write_io_threads        = 64
innodb_io_capacity             = 10000

# LOGGING #
log_error                      = /mnt/Storage/mysql/mysql-error.log
log_queries_not_using_indexes  = 1
slow_query_log                 = 1
slow_query_log_file            = /mnt/Storage/mysql/mysql-slow.log

一張插入性能較差的表的描述:

mysql> desc parts;
+------------+---------------------+------+-----+---------+----------------+
| Field      | Type                | Null | Key | Default | Extra          |
+------------+---------------------+------+-----+---------+----------------+
| ID         | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| binaryID   | int(11) unsigned    | NO   | MUL | 0       |                |
| messageID  | varchar(255)        | NO   |     |         |                |
| number     | bigint(20) unsigned | NO   | MUL | 0       |                |
| partnumber | int(10) unsigned    | NO   |     | 0       |                |
| size       | bigint(20) unsigned | NO   |     | 0       |                |
| dateadded  | datetime            | YES  | MUL | NULL    |                |
+------------+---------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

觀察#1

由於你的緩衝池是 6G(6144M),innodb_log_file_size應該是 1536M(6G 的 25%)

觀察#2

您將sync_binlog設置為 1。這提供了最安全的符合 ACID 的設置。它還可以顯著減慢速度。你說it seems as though its writing each row 1 at a time to disk。之所以如此,是因為每個完成的 DML(INSERT、UPDATE、DELETE)和 DDL(ALTER TABLE)語句都被寫入二進制日誌。sync_binlog 的預設值為 0。讓作業系統負責將二進制日誌更改刷新到磁碟。

觀察#3

您將innodb_io_capacity設置為 10000。這確實是您期望 mysql 的 10000 IOPS。嘗試降低它。

在這方面有一些事情要做

  • 當涉及到sync_binlog

    • 將其從 my.cnf 中註釋掉
    • 將 sync_binlog 設置為 100 或 200 以加快二進制日誌的刷新速度
  • 您應該確保數據磁碟具有電池支持的記憶體(具有良好的電池)

推薦

STEP 01) 在 my.cnf 中設置這些選項

[mysqld]
innodb_fast_shutdown = 0
innodb_log_file_size = 1536M
sync_binlog = ( you choose 0 or 100 )

步驟 02)刪除 innodb_io_capacity。讓它設置為預設值。

步驟 03) 在 mysql 中執行此命令

mysql> SET GLOBAL innodb_fast_shutdown = 0;

STEP 04) 應用設置

cd /mnt/Storage/mysql
service mysql stop
mv ib_logfile0 ib_logfile0.bak
mv ib_logfile2 ib_logfile1.bak
service mysql start

這應該加快速度

引用自:https://dba.stackexchange.com/questions/31793