mysql索引 物理文件_MySQL体系结构之物理文件
一、MySQL日志文件
mysql日志文件及功能:
日志文件
功能
錯誤日志
記錄啟動、停止、運行過程中mysqld時出現(xiàn)的問題
通用日志
記錄建立客戶端連接和執(zhí)行的語句
二進制日志
記錄更改數(shù)據(jù)的所有語句,還用于復(fù)制
慢查詢?nèi)罩?/p>
記錄執(zhí)行時間超過long_query_time秒的所有查詢
默認情況下,mysql所有日志均存儲于mysql數(shù)據(jù)目錄下。通過刷新日志,可以時mysqld強制關(guān)閉和打開日志文件(或者在某些情況下切換到下一個日志)。
刷新日志方法:
1)flush logs
2)mysqladmin flush-logs
3)mysqladmin refresh
1、錯誤日志
1)作用:記錄mysqld啟動、停止以及mysql數(shù)據(jù)庫在運行過程中發(fā)生的各種嚴重錯誤信息。當(dāng)數(shù)據(jù)庫發(fā)生任何故障導(dǎo)致無法重啟時,可以參考錯誤日志進行故障診斷。
2)位置:可以使用--log-error[=file_name]參數(shù)選項來指定mysqld保存錯誤日志文件的位置。如果沒有給定file_name文件位置,mysqld使用的錯誤日志名為host_name.err并默認保存在datadir指定的目錄下。
2、通用日志
1)作用:查詢?nèi)罩居涗浛蛻舳说乃姓Z句(所有連接和語句都記錄到通用日志),而binlog不記錄select語句。
2)位置:查詢?nèi)罩竞吐樵內(nèi)罩径伎梢员4嬖谖募虮碇?#xff0c;并使用參數(shù)--log-output[=value]來進行控制,value的值可以是table,file,none的一個或多個的組合,中間用逗號進行分割,分別表示日志保存在表,文件,不保存在表或文件中,這里的表指的是mysql庫總的general_log(慢查詢?nèi)罩臼莝low_log)表。其中none的優(yōu)先級最高,比如--log-output=table,file表示日志同時輸出到表和文件中,--log-output=table,none表示日志不保存在表中。如果不顯示使用此參數(shù),則表示日志輸出到文件中。一般日志輸出到表中要占用更多的系統(tǒng)資源。
如果要啟用查詢?nèi)罩?#xff0c;可以通過參數(shù)--general_log[={0|1}]和--general_log_file=file_name來進行控制。前者控制是否啟用查詢?nèi)罩?--general_log設(shè)置為1或者不帶值都可以啟用查詢?nèi)罩?#xff0c;設(shè)置為0表示關(guān)閉查詢?nèi)罩?#xff0c;不指定此參數(shù)表示不啟動查詢?nèi)罩?,后者控制日志文件的路徑。也可以使用--log[=file_name]或-l [file_name]選項啟動它,如果沒有給出file_name,那么默認值就是host_name.log。運行時可以通過set global general_log on打開通用日志。
如果沒有指定--general_log_file=file_name值,且沒有顯示設(shè)置--log_output參數(shù),那么日志默認寫入datadir目錄下的,默認文件名為host_name.log。這兩個參數(shù)都是global類型,可以在啟動時或系統(tǒng)運行時動態(tài)修改。如果想在session級別控制日志是否被記錄,則通過在session中設(shè)置參數(shù)sql_log_off為on或off來進行控制。
查詢通用日志位置:
mysql> show variables like 'gene%';
+------------------+--------------------------------------+
| Variable_name??? | Value??????????????????????????????? |
+------------------+--------------------------------------+
| general_log????? | OFF????????????????????????????????? |
| general_log_file | /usr/local/mysql/data/chavinking.log |
+------------------+--------------------------------------+
2 rows in set (0.00 sec)
3)日志內(nèi)容的讀取:查詢?nèi)罩緸槲谋疚臋n格式,一般直接讀取就可。
4)一般情況下不建議開啟查詢?nèi)罩竟δ?#xff0c;否則可能造成短時間內(nèi)磁盤占用率猛增。
3、慢查詢?nèi)罩?/p>
1)概述:當(dāng)參數(shù)slow_query_log=1時,慢查詢?nèi)罩居涗浟怂袌?zhí)行時間超過參數(shù)long_query_time設(shè)置值并且掃描記錄數(shù)不小于min_examined_row_limit的所有sql語句的日志(獲得表鎖定的時間不能算作執(zhí)行時間)。當(dāng)沒有給出慢查詢?nèi)罩久麜r,默認為主機名,后綴為-slow.log,當(dāng)給出了文件名,但不是絕對路徑,慢查詢?nèi)罩緯涗浀絤ysql的數(shù)據(jù)目錄下。執(zhí)行完語句并且釋放鎖后,即可記入慢查詢?nèi)罩?#xff0c;記錄順序可以與執(zhí)行順序不同。慢查詢?nèi)罩究梢圆檎覉?zhí)行時間長的語句,用于優(yōu)化,它是MySQL數(shù)據(jù)中常用的性能優(yōu)化工具。Long_query_time默認為10秒,最小為0,精度可以到微秒。
一般兩類語句不記錄到慢查詢?nèi)罩局?#xff1a;管理語句和不使用索引進行查詢的語句。如果要監(jiān)控這兩類SQL語句,可以分別通過參數(shù)--log-slow-admin-statements和log_queries_not_using_indexes進行控制。
2)文件位置和格式:慢查詢?nèi)罩灸J是關(guān)閉的,在mysql5.1.29前,當(dāng)用--log-slow-queries[=file_name]選項啟動mysqld時,慢查詢?nèi)罩鹃_始被記錄。和前幾種日志一樣,如果沒有指定file_name的值,日志將寫入datadir路徑,默認文件名為host_name-slow.log。在mysql5.1.29后,--log-slow-queries參數(shù)廢棄,采用兩個新的參數(shù)進行替換:--slow_query_log[={0|1}]顯示指定慢查詢?nèi)罩緺顟B(tài),如果不指定值或指定值為1都會打開慢查詢;使用slow_query_log_file[=file_name]來指定慢查詢?nèi)罩韭窂?#xff0c;另外還可以指定--log-output參數(shù)指定日志的輸出格式,默認輸出到文件。需要注意的是如果選擇輸出到表,則表中的記錄的慢查詢時間只能精確到秒,而日志文件中可以精確到微秒。
3)日志文件的讀取:慢查詢?nèi)罩疚募谴嫖谋痉绞酱鎯?#xff0c;可以直接讀取。也可以通過mysqldumpslow工具(../bin/mysqldumpslow faspdev-slow.log)對慢查詢?nèi)罩具M行匯總處理。慢查詢?nèi)罩就ǔS脕矶ㄎ籱ysql服務(wù)中sql問題,默認建議打開慢查詢?nèi)罩?#xff0c;并定期查看分析。
4)慢查詢?nèi)罩驹趍ysql性能優(yōu)化中的作用詳解:
4.1)慢查詢?nèi)罩靖袷?#xff1a;
mysql慢查詢標(biāo)準(zhǔn):
query_time:查詢耗時
rows_examined:檢查多少條記錄
rows_sent:返回多少行記錄
mysql使用以上幾點大致衡量sql成本。
其他信息包括如下:
time:執(zhí)行sql開始時間
lock time:等待table lock的時間,注意innodb行鎖等待不會反應(yīng)在這里。
user@host:執(zhí)行查詢的用戶和客戶端ip
以下是一個慢查詢例子:
# Time: 170122 13:53:17
# User@Host: root[root] @ localhost []? Id:???? 1
# Query_time: 9.839503? Lock_time: 0.000159 Rows_sent: 0? Rows_examined: 524288
SET timestamp=1485064397;
insert into column_charset? select * from column_charset;
一般執(zhí)行時間最長的sql是需要優(yōu)化的,如果檢查了大量數(shù)據(jù)而只返回少量數(shù)據(jù),則意味著質(zhì)量不佳。需要注意的是慢查詢?nèi)罩纠锏穆樵儾灰欢ň褪遣涣約ql,還可能受其他查詢影響,或者受到系統(tǒng)資源限制導(dǎo)致的。
4.2)如何識別需要關(guān)注的sql:
確認已經(jīng)開啟了慢查詢?nèi)罩?#xff0c;并且設(shè)置了合理的閾值。以下命令可以查看是否啟用慢查詢?nèi)罩疽约奥樵內(nèi)罩韭窂?#xff1a;
mysql> show variables like '%slow_query_log%';
+---------------------+------------------------------------------- ------------------------+
| Variable_name?????? | Value????????????????????????????????????? |
+---------------------+--------------------------------------------------------------------+
| slow_query_log????? | OFF??????????????????????????????????????? |
| slow_query_log_file | /usr/local/mysql5631/data/faspdev-slow.log |
+---------------------+-------------------------------------------------------------------+
以下命令可以查看全局變量long_query_time參數(shù)的值,所有超過該值得sql都將記錄到慢查詢?nèi)罩局?#xff1a;
mysql> show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name?? | Value???? |
+-----------------+-----------+
| long_query_time | 1.000000 |
+-----------------+-----------+
1 row in set (0.00 sec)
在mysql參數(shù)文件中開啟慢查詢?nèi)罩驹O(shè)置如下:
[mysqld]
slow_query_log=1
slow_query_log_file=/usr/local/mysql/data/log/slowquery.log
long_query_time=0.5
mysql 5.0慢查詢參數(shù)是不一樣的,且需要重啟后才可以生效,相關(guān)參數(shù)為log_slow_queries和slow_launch_time。
參數(shù)log-queries-not-using-indexes用于指定如果沒有使用到索引或雖然使用了索引但仍然遍歷了所有記錄,就將其記錄下來,默認此參數(shù)是關(guān)閉的。
4.3)使用工具分析慢查詢?nèi)罩?/p>
如果慢查詢?nèi)罩緝?nèi)容比較多,對于分析是比較麻煩的,一般有以下兩種辦法可以參考:
u 調(diào)整閾值
u 使用命令、腳本、工具進行分析,如mysqldumpslow、pt-query-digest等。
A. 使用操作系統(tǒng)命令進行分析:
可以使用shell命令進行統(tǒng)計分析,如grep、awk、wc,但是這些工具不容易實現(xiàn)高級功能。
awk '/^#Time:/{print $3,$4,c;c=0}/^#User/{c++}' mysql-slow.log > /mnt/slowquery.log
B. 使用mysqldumpslow工具進行分析:
mysqldumpslow工具是官方自帶的,此工具可以獲得日志中的查詢摘要。以下是mysqldumpslow工具使用幫助:
$mysqldumpslow --help
Usage: mysqldumpslow [ OPTS... ] [ LOGS... ]
Parse and summarize the MySQL slow query log. Options are
--verbose??? verbose
--debug????? debug
--help?????? write this text to standard output
-v?????????? verbose
-d?????????? debug
-s ORDER???? what to sort by (t, at, l, al, r, ar etc), 'at' is default
-r?????????? reverse the sort order (largest last instead of first)
-t NUM?????? just show the top n queries
-a?????????? don't abstract all numbers to N and strings to 'S'
-n NUM?????? abstract numbers with at least n digits within names
-g PATTERN?? grep: only consider stmts that include this string
-h HOSTNAME? hostname of db server for *-slow.log filename (can be wildcard),
default is '*', i.e. match all
-i NAME????? name of server instance (if using mysql.server startup script)
-l?????????? don't subtract lock time from total time
查詢時間最長的10個sql:
mysqldumpslow -t 10 mysql-slow.log
查詢訪問次數(shù)最多的10個sql命令:
mysqldumpslow -s c -t 10 mysql-slow.log
查詢訪問記錄最多的10條sql命令:
mysqldumpslow -s r -t 10 mysql-slow.log
4.4)以下是mysql運行狀態(tài)下設(shè)置慢查詢?nèi)罩镜睦?/p>
mysql> show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name?? | Value???? |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.00 sec)
mysql> set long_query_time=2;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like '%slow_query_log%';
+---------------------+--------------------------------------------+
| Variable_name?????? | Value????????????????????????????????????? |
+---------------------+--------------------------------------------+
| slow_query_log????? | OFF??????????????????????????????????????? |
| slow_query_log_file | /usr/local/mysql5631/data/faspdev-slow.log |
+---------------------+--------------------------------------------+
2 rows in set (0.00 sec)
mysql> set global slow_query_log=1;
Query OK, 0 rows affected (0.00 sec)
4、binlog日志文件
1)作用:Binlog記錄了數(shù)據(jù)庫所有的ddl語句和dml語句,但不包括select語句內(nèi)容,語句以事件的形式保存,描述了數(shù)據(jù)的變更順序,binlog還包括了每個更新語句的執(zhí)行時間信息,binlog主要作用是用于恢復(fù)數(shù)據(jù),因此binlog對于災(zāi)難恢復(fù)和備份恢復(fù)來說至關(guān)重要。相當(dāng)于oracle數(shù)據(jù)庫中的archivelog文件。
binlog還用于實現(xiàn)mysql主從復(fù)制。
二進制日志文件記錄了數(shù)據(jù)庫的變更過程,對于數(shù)據(jù)庫的安全性和完整性起著至關(guān)重要的作用。
2)位置和格式:當(dāng)用--log-bin[=file_name]選項啟動時,mysqld開始將數(shù)據(jù)庫變更情況寫入日志文件。如果沒有給出file_name值,默認名為主機名-bin。如果給出了文件名,但不包含路徑,則文件默認被寫入datadir參數(shù)指定路徑。
mysqld將在每個binlog日志名后添加一個數(shù)字擴展名,每次要啟動服務(wù)器或刷新日志時,該數(shù)字將會增加,如果當(dāng)前日志大小達到了max-binlog-size參數(shù)設(shè)置的值,那么mysqld會自動創(chuàng)建新的二進制日志。
mysqld還將創(chuàng)建一個binlog索引文件,其中包含了所有binlog文件的文件名,默認該索引文件與binlog文件名相同,擴展名為.index。當(dāng)mysqld運行時,不可以手工編輯該索引文件,這樣可能導(dǎo)致mysqld異常。當(dāng)rm刪除binlog后,你也許不得不手工編輯索引文件。
3)binlog日志格式
mysql有兩種記錄命令方式,一種是語句級(binlog_format=statement),一種是行級(binlog_format=row),建議命令格式設(shè)置為混合模式(binlog_format=mixed),這在大部分模式下試用,它在一般情況下試用語句級記錄,但是在一些特殊情況下試用行級記錄,這增加了復(fù)制的健壯性。
Mysq5.5中,二進制日志格式分為3種:statement,row和mixed,可以在啟動數(shù)據(jù)庫時通過參數(shù)--binlog_format進行設(shè)置,這3種格式區(qū)別如下:
3.1)statement:
Mysql5.1之前的版本都采用這種方式,binlog日志中記錄的都是語句(基于語句級的日志里包含了原始執(zhí)行的sql語句,還有其他信息,如執(zhí)行語句的線程id,語句執(zhí)行的時間戳,執(zhí)行所消耗時長),每一條對數(shù)據(jù)庫造成修改的語句都會記錄在日志中,通過mysqlbinlog工具,可以清晰的看到每條語句的文本。主從復(fù)制時,從庫的日志解析為原文本在從庫中執(zhí)行。優(yōu)點是日志量小,清晰易懂,對io壓力小,缺點是某些情況下slave的日志復(fù)制會出差。
3.2)row:
Mysql5.1.11之后出現(xiàn)的。它將每一行變更記錄到日志中,而不是記錄sql語句(記錄行的更改信息而不是語句)。優(yōu)點是記錄每一行數(shù)據(jù)變化的細節(jié),不會出現(xiàn)slave模式下某些情況無法復(fù)制的情況。缺點是日志量大,對io影響較大。通過mysqlbinlog默認看到的都是經(jīng)過base-64編碼的信息,mysqlbinlog加參數(shù)-verbose(或-v)將會生成帶注釋的語句,如果連續(xù)兩次使用這個參數(shù)(如-v -v),則生成字段類型、長度、是否為null等屬性信息。
一般而言,row模式更為健壯,而statement級別如果應(yīng)用了mysql的一些額外特性,比如存儲過程、觸發(fā)器,則可能導(dǎo)致復(fù)制異常,所以,如果使用語句級記錄,那么需要保持mysql數(shù)據(jù)庫應(yīng)用的簡單性,即只用核心功能即可。
3.3)mixed:
這是目前mysql的默認binlog日志格式,即混合了statement和row兩種日志。默認情況下采用statement,但是在一些特殊情況下采用row方式記錄日志。此種模式利用statement和row的優(yōu)點,而盡量避開他們的缺點。
注意:可以在global和session級別對binlog日志的格式進行修改。
4)日志文件的讀取
由于binlog以二進制方式存儲,不能直接讀取,因此需要使用mysqlbinlog工具進行日志分析,語法:mysqlbinlog log-file。
例:
4.1)以binlog方式啟動數(shù)據(jù)庫:
[root@faspdev bin]# ./mysqld_safe --user=mysql --log-bin=binlog-test
4.2)執(zhí)行dml語句:
mysql> delete from t1;
Query OK, 2 rows affected (0.02 sec)
4.3)mysqlbinlog查看binlog內(nèi)容:
[root@faspdev data]# ../bin/mysqlbinlog binlog-test.000001
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#161111 17:45:52 server id 1? end_log_pos 120 CRC32 0x5bfb8e4f Start: binlog v 4, server v 5.6.31-log created 161111 17:45:52 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
UJMlWA8BAAAAdAAAAHgAAAABAAQANS42LjMxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABQkyVYEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAU+O
+1s=
'/*!*/;
# at 120
#161111 17:47:29 server id 1? end_log_pos 199 CRC32 0x3f0abe26 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1478857649/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1075838976/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 199
#161111 17:47:29 server id 1? end_log_pos 287 CRC32 0x78e57a7e Query thread_id=1 exec_time=0 error_code=0
use `test`/*!*/;
SET TIMESTAMP=1478857649/*!*/;
delete from t1
/*!*/;
# at 287
#161111 17:47:29 server id 1? end_log_pos 318 CRC32 0x0b2d7e98 Xid = 9
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
如果日志格式是row,mysqlbinlog解析的文件是無法讀懂的字符,可以加-v或-v -v進行查看。
5)默認情況下,并不是每次寫入時都將binlog與磁盤同步,因此操作系統(tǒng)或機器發(fā)生故障,那么binlog中最后的語句有可能會丟失。要防止這種情況發(fā)生,可以設(shè)置sync_binlog全局變量為n(1為最安全的值,同時也是最慢的),使binlog每n此寫入就與磁盤做同步。
6)日志文件的刪除
查看binlog方法:
mysql> show binary logs;
6.1)方法1:reset master刪除所有的binlog日志文件,刪除后的日志文件從1開始編號。
mysql> reset master;
Query OK, 0 rows affected (0.00 sec)
6.2)方法2:使用purge binary logs命令刪除部分binlog文件:
mysql> purge binary logs to 'mysql-bin.000001';
Query OK, 0 rows affected (0.03 sec)
6.3)方法3:purge master logs to ‘mysql-bin.******’命令,該命令刪除‘******’編號之前的所有日志文件。
6.4)方法4:purge master logs before ‘yyyy-mm-dd hh24:mi:ss’命令,該命令刪除‘yyyy-mm-dd hh24:mi:ss’日期之前的所有日志。
6.5)設(shè)置參數(shù)--expire_logs_days=#,此參數(shù)含義是設(shè)置日志過期天數(shù), 過了指定天數(shù)后的日志將會被自動刪除,這樣有利于減少DBA管理日志的工作量。
7)mysqlbinlog解析:
u # at 199
u #161111 17:47:29 server id 1? end_log_pos 287
u # Query thread_id=1 exec_time=0 error_code=0
8)binlog管理相關(guān)參數(shù)
8.1)--binlog-do-db=db_name:該參數(shù)告訴主服務(wù)器,如果當(dāng)前的數(shù)據(jù)庫是db_name,應(yīng)該將其記錄到binlog中,其他沒有被指定的數(shù)據(jù)庫將被忽略,可多次使用,對多個數(shù)據(jù)庫進行定義。
8.2)--binlog-ignore-db=db_name:改參數(shù)告訴主服務(wù)器,如果當(dāng)前數(shù)據(jù)庫為db_name,則不記錄binlog,其他沒有指定的數(shù)據(jù)庫變化將記錄binlog中,可多次使用,對多個數(shù)據(jù)庫進行定義。
8.3)--innodb-sage-binlog:該參數(shù)經(jīng)常和--sync-binlog=N(沒寫N次日志同步磁盤)一起配合使用,使得事務(wù)在日志中的記錄更加安全。
8.4)Set sql_log_bin=0:具有super權(quán)限的客戶端可以通過此語句禁止將自己的語句記錄二進制文件,這個選項在某些環(huán)境下是有用的,比如主主切換,或者mysql版本升級,但是使用一定倍加小心,免得造成slave環(huán)境下的數(shù)據(jù)不一致。
5、日志文件維護
很多生產(chǎn)環(huán)境,日志文件可以占用大量的磁盤空間,因此,需要對日志文件進行定期清理操作,mysql服務(wù)器當(dāng)然也不例外。
l 對于錯誤日志文件,一般不會太大,因此生產(chǎn)上注意一下就可以了。
l 通用日志一般生產(chǎn)不開啟,因此也不存在清理一說。
l 慢查詢?nèi)罩驹诼樵兒芏嗟那闆r下可能變得很大,可以手工清理或編寫腳本管理。
l binlog日志文件可以設(shè)置合適的過期策略,如expire-logs-days=10,表示設(shè)置binlog過期時間為10天。expires-logs-days設(shè)置會在運行flush logs命令后觸發(fā)刪除過期日志,注意,不能使用rm刪除binlog日志文件,這可能導(dǎo)致你執(zhí)行日志清理命令失敗。mysql 5.6可以設(shè)置保留binlog日志文件大小,避免磁盤對填滿。
二、innodb數(shù)據(jù)文件和日志文件
1、以下簡單介紹mysql數(shù)據(jù)目錄下的文件:
1)db.opt
數(shù)據(jù)庫結(jié)構(gòu)定義和設(shè)置
2)*.frm
數(shù)據(jù)表的結(jié)構(gòu)定義
3)*.MYD
Myisam引擎表數(shù)據(jù)
4)*.MYI
Myisam引擎索引數(shù)據(jù)
5)ibdata*
Innodb表空間數(shù)據(jù)文件
如果將innodb_file_per_table設(shè)置為1,那么innodb數(shù)據(jù)表可以各自存儲為一個文件,這種模式成為獨立表空間。如果將innodb_file_per_table設(shè)置為0,那么innodb數(shù)據(jù)則可以統(tǒng)一存儲在一個共享表空間里。
6)ib_logfile*
Innodb重做日志文件
7)*.idb
Innodb數(shù)據(jù)和索引。
8)*.trg
觸發(fā)器
2、innodb數(shù)據(jù)文件和日志文件
如果沒有再參數(shù)文件中指定innodb相關(guān)參數(shù),那么mysql將會在data目錄下創(chuàng)建一個大小為10m的ibdata1文件和大小5m的兩個ib_logfile*文件。這種設(shè)置對于生產(chǎn)而言太小,一般建議設(shè)置logfile為256m,數(shù)據(jù)文件初始大小1g~5g,并且設(shè)置自動增長。
參數(shù)配置樣例:
Innodb_data_file_path=ibdata1:1000m:autiextend
Innodb_log_file_size=256m
Innodb_data_file_path的值可以設(shè)置為1個或多個列表。如果要命名一個以上的數(shù)據(jù)文件,請用“;”分隔它們。其語法格式為:Innodb_data_file_path=datafile01:size[;datafile02:size;...]。
例如:Innodb_data_file_path=datafile01:2000m;datafile02:2000m;datafile03:2000m:autoextend
其中autoextend及其后屬相只能用于Innodb_data_file_path列表中最后一個數(shù)據(jù)文件,針對于最后一個數(shù)據(jù)文件,如果innodb共享表空間耗盡后,就會擴展最后一個數(shù)據(jù)文件,默認擴展大小為8m。
1)innodb獨立表空間和共享表空間
共享表空間使用簡單,方便維護,但是也存在缺點,使用貢獻表空間明顯的缺點是不能快速回收刪除大表的空間,io操作可能會消耗更多的資源等待。而獨立表空間是大部分DBA推薦使用的方式,它恰好在這一點彌補了共享表空間不足。Innodb下使用獨立表空間,每個表都有它自己的表空間。
開啟獨立表空間方式:
在my.cnf文件中添加如下參數(shù),重啟mysql實例即可生效:
[mysqld]
innodb_file_per_table
重啟實例后,innodb將會把新創(chuàng)建的表存儲到數(shù)據(jù)目錄下的文件tb1_name.ibd中,這類似域myisam存儲引擎所做的事,但是myisam把表分成數(shù)據(jù)文件tb1_name.MYD和索引文件tb1_name.MYI。對于innodb,數(shù)據(jù)和索引會放在一起,都存放到.ibd文件中,不過tb1_name.frm文件照舊會被創(chuàng)建。
在my.cnf文件中刪除了innodb_file_per_table行,重啟實例后,innodb新創(chuàng)建的表會存儲在共享表空間里,就是說innodb_file_per_table這個參數(shù)僅影響表的創(chuàng)建位置。innodb使用獨立表空間,也仍然有一部分數(shù)據(jù)在共享表空間里。
相對于myisam引擎管理的表,我們不能隨意移動.ibd文件,這是因為表定義是被存儲在innodb共享表空間里的,而innodb必須保持事務(wù)id和事務(wù)日志順序號的一致性。
2)innodb增加數(shù)據(jù)文件
手動增加一個innodb數(shù)據(jù)文件時需要重啟實例。為innodb存儲引擎管理表添加數(shù)據(jù)文件需要修改my.cnf參數(shù)文件,把innodb_data_file_path參數(shù)指定添加的數(shù)據(jù)文件及其初始大小和相關(guān)參數(shù)。注意當(dāng)你添加一個數(shù)據(jù)文件到innodb_data_file_path時,需要確定它不存在,當(dāng)你重啟實例時,innodb會自動創(chuàng)建這個數(shù)據(jù)文件。添加innodb數(shù)據(jù)文件需要首先計算當(dāng)前innodb_data_file_path中最后一個數(shù)據(jù)文件大小,然后估計一個近似值給它,再添加新的數(shù)據(jù)文件。Innodb數(shù)據(jù)文件只有最后一個可以設(shè)置為自動擴展。
3)改變innodb重做日志大小
不要試圖通過直接更改配置文件來設(shè)置innodb事務(wù)日志大小,這會導(dǎo)致不能啟動數(shù)據(jù)庫。如果想要改變innodb事務(wù)日志的數(shù)量和大小,必須正常關(guān)閉mysql實例,然后復(fù)制舊日志文件到一個安全的地方做備份,然后從日志文件目錄刪除所有的舊日志文件,之后更改my.cnf參數(shù)文件改變?nèi)罩疚募渲?#xff0c;并再次啟動mysql實例。Mysqld在啟動時會發(fā)現(xiàn)沒有重做日志文件,然后告訴你它正在創(chuàng)建一個新的日志文件。
更改innodb事務(wù)日志步驟:
l 干凈關(guān)閉mysql實例
l 使用mv命令轉(zhuǎn)移innodb重做日志文件。
l 修改my.cnf配置文件,更改innodb_log_file_size
l 啟動mysql實例
注意,舊版本mysql服務(wù)器重做日志總大小不能超過4g,在mysql5.6以后,限制擴展到521g。
4)innodb的undo區(qū)域
Undo區(qū)域也稱為undo空間或undo表空間,是innodb設(shè)計的一塊特殊存儲區(qū)域,它保存了被活動事務(wù)更改的數(shù)據(jù)的副本(鏡像),如果一個事務(wù)需要查看原來的數(shù)據(jù)(滿足一致性讀),那么可以從undo區(qū)域中獲得未被更改的數(shù)據(jù)。默認情況下,undo區(qū)域也是在innodb共享表空間內(nèi)。Mysql5.6以后提供了選項,可以把undo表空間獨立到表空間,這樣就可以進行熱點塊的io優(yōu)化,提升性能。
如果undo表空間暴漲,出現(xiàn)這種情況可能是因為負載比較大,或者存在長時間未提交的事務(wù)(長事務(wù))。
對于寫操作比較頻繁的應(yīng)用,innodb清理線程的速度可能會跟不上,從而導(dǎo)致undo表空間越來越大,可以通過設(shè)置innodb_max_purge_lag參數(shù)來避免undo空間過度增大。Innodb事務(wù)系統(tǒng)維持一個事務(wù)列表,該列表記錄被update或delete操作表示為刪除的索引記錄。這個列表的長度為purge_lag。當(dāng)purge_lag超過了nnodb_max_purge_lag時,每個dml語句都被延遲一定時間。
Undo空間里保存了數(shù)據(jù)的前鏡像,這是滿足一致性讀的根本原因,同時也是災(zāi)難恢復(fù)的重要角色(即回滾)。
3、臨時文件
Mysql臨時文件作用類似但不等同于oracle臨時表空間。Mysql使用環(huán)境變量TMPDIR的值作為保存臨時文件的目錄。如果未設(shè)置,則默認使用系統(tǒng)的默認值,一般為/tmp,/var/tmp,/usr/tmp。可以使用--tmpdir參數(shù)在啟動時指定mysql臨時目錄,或者在my.cnf文件中指定tmpdir參數(shù)進行分配。
如果mysql服務(wù)器正在作為復(fù)制服務(wù)器使用,那么不能將mysql臨時路徑指向基于內(nèi)存的文件系統(tǒng)目錄或者主機重啟會清空的目錄,否則可能造成復(fù)制失敗。Mysql隱含創(chuàng)建所有的臨時文件。進行排序操作時,mysql會使用一個或多個臨時文件。一定要保證臨時目錄空間夠用。一些普通的數(shù)據(jù)庫操作都有可能創(chuàng)建臨時文件用于維護數(shù)據(jù)庫內(nèi)的數(shù)據(jù)結(jié)構(gòu),alter table會在原表所在目錄下創(chuàng)建臨時表。
4、mysql套接字文件
服務(wù)器用來與本地客戶端進行通信的linux套接字文件(也稱為socket文件)默認位置是/tmp/mysql.sock。Scoket文件不建議放置在/tmp目錄下,可以將其單獨指定存儲位置,我們可以通過my.cnf配置文件指定mysql socket文件存儲路徑,下面是my.cnf中定義socket儲存路徑:
[mysqld]
Socket=/opt/mysql/mysql.socket
[client]
Socket=/opt/mysql/mysql.socket
Mysql服務(wù)器一定要保留root的除了socket外的其他登錄方式,比如通過127.0.0.1的root登錄賬號,以防止socket文件被刪除導(dǎo)致無法登錄mysql數(shù)據(jù)庫的窘境。
三、MySQL災(zāi)難恢復(fù)過程
1、預(yù)寫日志和undo表空間
mysql靠預(yù)寫日志(innodb事務(wù)日志)來保證數(shù)據(jù)持久性,也就是說數(shù)據(jù)文件不會先被寫入,而是先寫日志文件。innodb臟數(shù)據(jù)存在于innodb_buffer_pool里,它會按照一定的機制批量寫入磁盤,這樣可以提高吞吐率。
mysql宕機后的實例恢復(fù)過程:首先mysql找到事務(wù)日志中的某個點,從該點開始重做redo中的事務(wù),在應(yīng)用了所有redo日志后,根據(jù)undo區(qū)域確定哪些事務(wù)需要回滾,然后回滾哪些沒有提交的事務(wù),簡單理解,mysql災(zāi)難恢復(fù)過程就是根據(jù)redo重做日志,然后根據(jù)undo回退事務(wù)。
innodb事務(wù)日志很大程度上決定了數(shù)據(jù)的安全性,日志的持久性決定了災(zāi)難恢復(fù)后丟失多少數(shù)據(jù)!mysql可以通過參數(shù)控制commit時寫入事務(wù)日志的頻率,通常有以下3種情況:
1)innodb_flush_log_at_trx_commit=1
每次commit時都寫入磁盤,這樣理論上發(fā)生故障時我們只丟失一個事務(wù)。
2)innodb_flush_log_at_trx_commit=2
每次commit,只寫日志緩存到操作系統(tǒng)緩沖,但不刷新磁盤,innodb每秒刷新磁盤一次,所以故障丟失的是最近1秒的數(shù)據(jù)。生產(chǎn)環(huán)境建議這樣設(shè)置。
3)innodb_flush_log_at_trx_commit=0
每秒把日志緩沖的內(nèi)容寫入到日志文件,并且刷新到磁盤,但commit時什么也不做。
2、雙寫緩沖
數(shù)據(jù)文件的寫操作,可能會將塊寫壞,mysql設(shè)計了一個數(shù)據(jù)存儲區(qū)域雙寫緩沖,innodb使用雙寫緩沖來確保數(shù)據(jù)的安全,避免塊損壞。雙寫緩沖是innodb表空間的一個特殊區(qū)域,主要用于寫入頁的備份,并且是順序?qū)懭氲摹.?dāng)innodb刷新數(shù)據(jù)時,首先寫入雙寫緩沖,然后寫入數(shù)據(jù)文件。這樣既可確保所有寫操作的原子性和持久性。
崩潰重啟后,innodb會檢查每個塊的校驗和,判斷塊是否損壞,如果寫入雙寫緩沖的是壞塊,那么顯然沒有寫入實際數(shù)據(jù)文件,那么用數(shù)據(jù)文件的塊恢復(fù)雙寫緩沖;如果寫入了雙寫緩沖,但是數(shù)據(jù)文件中的是壞塊,那么使用雙寫緩沖中的塊恢復(fù)實際數(shù)據(jù)文件中的塊。這樣的機制提供了雙層的安全保障,但是缺點是增加了io。
對于讀取操作,innodb通過頁校驗和來保證數(shù)據(jù)的存取,每頁在內(nèi)存中都先算好一個校驗值,放在文件頭部,寫入的時候先寫校驗值,讀的時候也會校驗一下校驗值。
四、mysql參數(shù)文件及參數(shù)修改方法
MySQL數(shù)據(jù)庫初始化參數(shù)由參數(shù)文件來設(shè)置,如果沒有設(shè)置參數(shù)文件,mysql就按照系統(tǒng)中參數(shù)的默認值來啟動。在windows和linux上,參數(shù)文件可以被放在多個位置,數(shù)據(jù)庫啟動時按照不同的順序來搜索,如果多個位置都有參數(shù)文件,則搜索順序靠后的參數(shù)文件中的參數(shù)將覆蓋前的參數(shù)。
表:linux下mysql參數(shù)文件讀取順序:
參數(shù)文件名
目的
/etc/my.cnf
全局選項
$MYSQL_HOME/my.cnf
服務(wù)器相關(guān)選項
Default-extra-file
用--Default-extra-file=path選項指定的文件,如果該文件存在的話
~/.my.cnf
用戶相關(guān)選項
Mysql安裝上述順序?qū)ふ覅?shù)文件,如果多個文件同時存在,那么文件中指定的后讀取的選項要優(yōu)先于先讀取的選項,所以數(shù)據(jù)目錄或安裝目錄下的配置文件都有可能生效,所以理論上在數(shù)據(jù)目錄或安裝目錄下放置一個my.cnf文件即可。Mysql啟動時可以指定--datadir用于指定數(shù)據(jù)路徑,但是此選項對于查詢參數(shù)文件無效,因為在讀取--datadir之前mysql服務(wù)器就已經(jīng)讀取了配置文件了。多次指定一個選項,后出現(xiàn)的將覆蓋先出現(xiàn)的值,因此命令行中通過set修改的選項優(yōu)先級最高。
通過如下命令可以列出mysqld讀取參數(shù)文件的優(yōu)先順序:該命令不能在生產(chǎn)環(huán)境隨意運行
$mysqld --verbose --help |grep my.cnf
/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf
Mysql參數(shù)可以在3個級別進行更改:
1)session級別:set
2)全局級別:set global
3)永久級別:my.cnf
附:一份生產(chǎn)可用的mysql配置文件(my.cnf)示例(測試庫mysql 5.6.24):
[client]
#客戶端選項設(shè)置
port = 3306
socket = /opt/mysql-5.6.24/data/mysql.socket
#設(shè)置客戶端和連接字符集
default_character_set = utf8
[mysqld]
#服務(wù)器端選項設(shè)置
# innodb設(shè)置
default_storage_engine = InnoDB
innodb_strict_mode = 1
innodb_buffer_pool_size = 256M????? #mysql數(shù)據(jù)庫服務(wù)器,該值可設(shè)為物理內(nèi)存的50%-80%之間
innodb_stats_on_metadata = 0
innodb_file_format = Barracuda
innodb_data_file_path=ibdata1:10m:autoextend
innodb_flush_method = O_DIRECT
innodb_log_files_in_group = 2
innodb_log_file_size = 16M
innodb_log_buffer_size = 8M
innodb_file_per_table = 1
innodb_max_dirty_pages_pct = 60
innodb_io_capacity = 200
innodb_flush_log_at_trx_commit = 2
# 基本設(shè)置
basedir = /opt/mysql-5.6.24
datadir = /opt/mysql-5.6.24/data
port = 3306
server_id = 19900315
tmpdir = /opt/mysql-5.6.24/tmp
socket = /opt/mysql-5.6.24/tmp/mysql.socket
Pid-file = /opt/mysql-5.6.24/data/mysql.pid
skip-name-resolve = 1
skip-external-locking = 1
max_connect_errors = 500
max_connections = 1000
relay-log = mysql-relay-bin
log-slave-updates = 1
skip_slave_start = 1
read_only = 0
key_buffer_size = 8M
tmp_table_size = 8M
max_heap_table_size = 8M
query_cache_type = 0
query_cache_size = 0
thread_cache_size = 1024
open_files_limit = 65535
table_open_cache = 1024
max_allowed_packet = 16M
gtid-mode = ON
enforce-gtid-consistency = 1
lower_case_table_names=1
log-bin-trust-function-creators
plugin-load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
replicate-ignore-table = mysql.ibbackup_binlog_marker
slave-skip-errors = ddl_exist_errors
relay-log-info-repository = TABLE
relay_log_recovery = 1
master_info_repository = TABLE
# 服務(wù)器字符集設(shè)置
character_set_server = utf8
# error log設(shè)置
log_error = /opt/mysql-5.6.24/data/mysql.err
# slow log設(shè)置
slow_query_log = 1
slow_query_log_file = /opt/mysql-5.6.24/data/mysql-slow.log
long_query_time = 0.5
# binlog設(shè)置
binlog_format = mixed
log-bin = /opt/mysql-5.6.24/logs/mysql-bin
sync_binlog = 2
max_binlog_size = 16M
expire_logs_days = 10
#others設(shè)置
join_buffer_size = 128M
sort_buffer_size = 2M
read_rnd_buffer_size = 2M
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
總結(jié)
以上是生活随笔為你收集整理的mysql索引 物理文件_MySQL体系结构之物理文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 变量生命周期_Go: 延长变
- 下一篇: python tkinter text改