mysql學習記錄(二十)–MysqlServer參數調整

一、理論:
1.內存優化原則:
a.將盡量多的內存分配給mysql做緩存,但要給操作系統和其他程式預留足夠的內存,否則將產生SWAP頁交換,影響自身性能
b.MyISAM的數據文件讀取依賴於操作系統自身的IO緩存,因此,如果有MyISAM表,就要預留更多的內存給操作系統做IO緩存
c.排序區、連接區等緩存是分配給每個資料庫會話專用的,其默認值的設置要根據最大連接數合理分配。不能設置太大否則在並發連接較高時會導致物理內存耗盡
2.MyISAM內存優化:
a.key_buffer_size決定MyISAM索引塊緩存區的大小,它直接影響MyISAM表的存取效率。可以在mysql參數文件中設置key_buffer_size的值,對於一般MyISAM的資料庫建議至少將1/4可用內存分配給key_buffer_size
key buffer使用率計算公式如下:
1 – ( (key_blocks_unused * key_cache_block_size) / key_buffer_size )
在80%左右合適。大於80%將因索引緩存不足導致性能下降,小於80%會導致內存浪費 
b.使用多個索引緩存:
1)mysql通過各session共享key buffer提高瞭MyISAM索引存取的性能,但它並不能消除session間key buffer間的競爭。
3.調整LRU策略:
a.通過調節key_cache_pision_limit來控制多大比例的緩存用做warm子表。
在最後:
N * key_cache_age_threshold / 100次緩存命準內未被訪問過,就會被降級到warm子表
b.調整read_buffer_size和read_md_buffer_size
c.如帶用order by子句,可以適當增大read_rnd_buffer_size的值。但read_rnd_buffer_size的值也是按session分配的
4.InnoDB內存優化:
a.InnoDB用一塊內存區做IO緩存池,該緩存池不僅用來緩存InnoDB的索引塊,而且也用來緩存InnoDB的數據塊。與MyISAM不同
b.在內部,InnoDB緩存池邏輯上由free list、flush list、LRU list組成。顧名思義,free list是空閑緩存塊列表,flush list是需要緩新到磁盤的緩存塊列表,而LRU list是InnoDB正在使用的緩存塊,它是InnoDB buffer pool的核心。
InnoDB使用LRU算法與MyISAM的‘中點插入策略’LRU算法類似。
臟頁的刷新
c.可以通過調整InnoDB buffer pool的大小,改變young sublist和old sublist的分配比例、控制臟緩存的刷新活動、使用多個InnoDB緩存池等方法來優化InnoDB的性能
5.innodb_buffer_pool_size的設置:
a.innodb_buffer_pool_size決定InnoDB存儲引擎表數據和索引數據的最大緩存區大小。innodb buffer pool同時為數據塊和索引塊提供數據緩存,若innodb_buffer_pool_size值越大,緩存命中率越高,訪問InnoDB表需要的磁盤I/O就越少,性能也就越高。
可以通過:
mysqladmin -S /tmp/mysql.sock ext | grep -i innodb_buffer_pool
查看buffer pool的使用情況
可用以下公式InnoDB緩存池的命中率:
( 1- innodb_buffer_pool_reads/innodb_buffer_pool_read_request) * 100
若太低則應該擴充內存、增加innodb_buffer_pool_size的值
6.調整innodb_old_blocks_time的設置:
a.innodb_old_blocks_time參數決定瞭緩存數據塊由old sublist轉移到young sublist的快慢,當一個緩存數據塊被插入到midpoint(old sublist)後,至少要在old sublist停留超過innodb_old_blocks_time(ms)後,才有可能被轉移到new sublist.
可以根據InnoDB Monitor的輸出信息來調整innodb_old_blocks_time的值,在進行表掃描時,如果non-youngs/s很低,young/s很高,就應考慮將innodb_old_blocks_time適當調大,以防止表掃描將真正的熱數據淘汰,此值可以進行動態設置
7.調整緩存池數量,減少內部對緩存池數據結構的爭用:
a.InnoDB的緩存系統引入瞭innodb_buffer_pool_instances配置參數。對於較大的緩存池,適當增大此參數的值,可以降低並發導致的內部緩存訪問沖突,改善性能。InnoDB緩存系統會將參數innodb_buffer_pool_size指定大小的緩存平分為innodb_buffer_pool_instances個buffer pool.
8.控制innodb buffer刷新,延長數據緩存時間,減緩磁盤I/O
a.innodb buffer pool的刷新快慢主要取決於兩個參數
1)innodb_max_dirty_pages_pct:控制緩存池中臟頁的最大比例,默認值是75%,如果臟頁的數量達到或超過該值,innoDB後臺線程將開臺緩存刷新
2)innodb_io_capacity:在某種程度上代表磁盤中每秒可完成的I/O次數,對於轉速較低的磁盤,可將innodb_io_capacity降低。對於固態磁盤和由多個磁盤組成的陣列,innodb_io_capacity的值可適當增大
3)如無法增大緩存池,應將innodb_max_dirty_pages_pct的值調小,將innodb_io_capactity的值提高,以加快臟頁的刷新
9.InnoDB doublewrite:
a.在做恢復時,如果發現不一致的頁,InnoDB會用系統表空間double buffer區的相應副本來恢復數據頁
b.由於同步到doublewrite buffer是對連續磁盤空間的順序寫,因此開啟雙寫對性能的影響並不太大。對需要高性能並且可以容忍丟失數據的應用,可將innodb_doublewrite=0來關閉雙寫以滿足性能
10.調整用戶服務線程排序緩存區:
a.若查看show global status看到sort_merge_passes的值很大,則可以調整參數sort_buffer_size的值來調整排序緩存區,以改善order by子句或group子句的sql性能
b.可通過調整join_buffer_size的值來改善沒使用索引的查詢
c.最好的策略是設置較小的全局join_buffer_size,對較復雜的操作session單獨設置join_buffer_size
11.InnoDB log機制及優化:
a.innodb_flush_log_at_trx_commit的設置:
0:每秒觸發一次,可滿足持久化要求(效率最高,但最不安全)
1:每個事務提交時立刻將緩存中的redo日志回寫到日志文件,並調用操作系統fsync刷新IO緩存(默認值,效率最低,但最安全)
2:每個事務提交時,InnoDB立刻將redo日志回寫到日志文件,但並不馬上調用fsync來刷新IO緩存,而是每秒隻做一次磁盤IO緩存刷新操作(性能和數據安全性都在中間)
12.設置log file size,控制檢查點:
a.可以通過一些方法計算innodb每小時產生的日志量並估計合適的innodb_log_file_size值
13.調整innodb_log_buffer_size:
a.可以通過增大innodb_log_buffer_size來減少日志寫磁盤操作,從而提高事務處理的性能
14.調整max_connections,提高並發連接:
a.max_connections控制允許連接到mysql資料庫的最大數量,默認值是151
15.調整back_log:
a.如果需要資料庫在較短時間內處理大量連接請求,可適當增大back_log的值
16.調整table_open_cache:
a.在未執行flush tables命令的情況下,如果mysql狀態變量opened_tables的值較大,就說明table_open_cache設置的太小,應適當增大
17.調整thread_cache_size:
a.可以通過計算cache的失敗率threads_created/connections來衡量thread_cached_size的值是否合適。此值越接近1,說明線程cache命中率越低,應考慮適當增加thread_cache_size的值
18.innodb_lock_wait_timeout的設置:
a.innodb_lock_wait_timeout可以控制innodb事務等待行鎖的時間,默認值是50ms.
b.對於需要快速反饋的交互式OLTP應用,可以將行鎖等待超時時間調小,以避免事務長時間掛起
c.對於後臺運行的批處理操作,可以將行鎖等待超時時間調大,以避免發生大的回滾操作
二、實踐:

 

mysql> use sakila;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A


Database changed
mysql> show engine innodb status \G;
*************************** 1. row ***************************
  Type: InnoDB
  Name: 
Status: 
=====================================
151102  7:13:01 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 15 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 113 1_second, 113 sleeps, 7 10_second, 47 background, 47 flush
srv_master_thread log flush and writes: 113
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 18, signal count 18
Mutex spin waits 8, rounds 240, OS waits 7
RW-shared spins 11, rounds 330, OS waits 11
RW-excl spins 0, rounds 0, OS waits 0
Spin rounds per wait: 30.00 mutex, 30.00 RW-shared, 0.00 RW-excl
------------
TRANSACTIONS
------------
Trx id counter B0A
Purge done for trx's n:o < 920 undo n:o < 0
History list length 103
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 28, OS thread handle 0x7f5dbdfe6700, query id 568 localhost root
show engine innodb status
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (read thread)
I/O thread 4 state: waiting for i/o request (read thread)
I/O thread 5 state: waiting for i/o request (read thread)
I/O thread 6 state: waiting for i/o request (write thread)
I/O thread 7 state: waiting for i/o request (write thread)
I/O thread 8 state: waiting for i/o request (write thread)
I/O thread 9 state: waiting for i/o request (write thread)
Pending normal aio reads: 0 [0, 0, 0, 0] , aio writes: 0 [0, 0, 0, 0] ,
 ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
586 OS file reads, 55 OS file writes, 48 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 0 merges
merged operations:
 insert 0, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 553229, node heap has 1 buffer(s)
0.00 hash searches/s, 0.00 non-hash searches/s
---
LOG
---
Log sequence number 13476957
Log flushed up to   13476957
Last checkpoint at  13476957
0 pending log writes, 0 pending chkp writes
32 log i/o's done, 0.00 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 274726912; in additional pool allocated 0
Dictionary memory allocated 182244
Buffer pool size   16383
Free buffers       15829
Database pages     553
Old database pages 224
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 553, created 0, written 27
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 553, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
Main thread process no. 62305, id 140040552920832, state: waiting for server activity
Number of rows inserted 5, updated 0, deleted 0, read 12
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================


1 row in set (0.00 sec)


ERROR: 
No query specified

mysql> set global hot_cache.key_buffer_size = 128* 1024;
Query OK, 0 rows affected (0.00 sec)

mysql> set global hot_cache.key_buffer_size = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'key_buffer_size';
+-----------------+----------+
| Variable_name   | Value    |
+-----------------+----------+
| key_buffer_size | 33554432 |
+-----------------+----------+
1 row in set (0.00 sec)

mysql> set global key_buffer_size = 0;
ERROR 1438 (HY000): Cannot drop default keycache
mysql> show warnings;
+-------+------+------------------------------+
| Level | Code | Message                      |
+-------+------+------------------------------+
| Error | 1438 | Cannot drop default keycache |
+-------+------+------------------------------+
1 row in set (0.00 sec)


mysql> cache index sales,sales2 in hot_cache;
+---------------+--------------------+----------+-------------------------------------+
| Table         | Op                 | Msg_type | Msg_text                            |
+---------------+--------------------+----------+-------------------------------------+
| sakila.sales  | assign_to_keycache | Error    | Table 'sakila.sales' doesn't exist  |
| sakila.sales  | assign_to_keycache | status   | Operation failed                    |
| sakila.sales2 | assign_to_keycache | Error    | Table 'sakila.sales2' doesn't exist |
| sakila.sales2 | assign_to_keycache | status   | Operation failed                    |
+---------------+--------------------+----------+-------------------------------------+
4 rows in set (0.00 sec)

mysql> set global key_cache_pision_limit = 70;
Query OK, 0 rows affected (0.00 sec)

mysql> set global hot_cache.key_cache_pision_limit = 70;
Query OK, 0 rows affected (0.00 sec)

mysql> show global variables like '%innodb_old_blocks_pct%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_old_blocks_pct | 37    |
+-----------------------+-------+
1 row in set (0.01 sec)


mysql> show global variables like '%doublewrirte%';
Empty set (0.00 sec)

mysql> show global variables like '%doublewrite%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| innodb_doublewrite | ON    |
+--------------------+-------+
1 row in set (0.01 sec)

mysql> select @a1 := variable_value as a1;
ERROR 1054 (42S22): Unknown column 'variable_value' in 'field list'
mysql> select @a1 := variable_value as a1 
    -> from information_schema.global_status 
    -> where variable_name = 'innodb_os_log_written'
    -> union all
    -> select sleep(60)
    -> union all
    -> select @a2 := variable_value as a2
    -> from information_schema.global_status 
    -> where variable_name = 'innodb_os_log_written';
+------+
| a1   |
+------+
| 9216 |
| 0    |
| 9216 |
+------+
3 rows in set (1 min 0.02 sec)

mysql> select round((@a2-@a1)/1024/1024 / @@innodb_log_files_in_group) as MB;
+------+
| MB   |
+------+
|    0 |
+------+
1 row in set (0.01 sec)

You May Also Like