[TOC]mysql
sql
總之,存儲引擎的各項特性就是爲了保障數據庫的安全和性能設計結構。shell
MySQL 提供如下存儲引擎: 01)InnoDB數據庫
02)MyISAM 03)MEMORY 04)ARCHIVE 05)FEDERATED 06)EXAMPLE 07)BLACKHOLE 08)MERGE 09)NDBCLUSTER 10)CSVvim
還可使用第三方存儲引擎: 01)MySQL當中插件式的存儲引擎類型 02)MySQL的兩個分支 03)perconaDB 04)mariaDB緩存
#查看當前MySQL支持的存儲引擎類型 mysql> show engines; +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO | | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ 9 rows in set (0.00 sec) #查看innodb的表有哪些 mysql> select table_schema,table_name,engine from information_schema.tables where engine='innodb'; +--------------+----------------------+--------+ | table_schema | table_name | engine | +--------------+----------------------+--------+ | mysql | innodb_index_stats | InnoDB | | mysql | innodb_table_stats | InnoDB | | mysql | slave_master_info | InnoDB | | mysql | slave_relay_log_info | InnoDB | | mysql | slave_worker_info | InnoDB | +--------------+----------------------+--------+ 20 rows in set (0.03 sec) #查看myisam的表有哪些 mysql> select table_schema,table_name,engine from information_schema.tables where engine='myisam'; +--------------------+---------------------------+--------+ | table_schema | table_name | engine | +--------------------+---------------------------+--------+ | information_schema | COLUMNS | MyISAM | | information_schema | EVENTS | MyISAM | | mysql | help_category | MyISAM | | mysql | ndb_binlog_index | MyISAM | +--------------------+---------------------------+--------+ 33 rows in set (0.01 sec)
物理上的區別:安全
#進入mysql目錄 [root@db01~l]# cd /application/mysql/data/mysql #myisam [root@db01 mysql]# ll user.* -rw-rw---- 1 mysql mysql 10684 Mar 6 2017 user.frm -rw-rw---- 1 mysql mysql 960 Aug 14 01:15 user.MYD -rw-rw---- 1 mysql mysql 2048 Aug 14 01:15 user.MYI #進入word目錄 [root@db01 world]# cd /application/mysql/data/world/ #innodb [root@db01 world]# ll city.* -rw-rw---- 1 mysql mysql 8710 Aug 14 16:23 city.frm -rw-rw---- 1 mysql mysql 688128 Aug 14 16:23 city.ibd
在MySQL5.5版本以後,默認的存儲引擎,提供高可靠性和高性能。服務器
優勢: 01)事務安全(聽從 ACID) 02)MVCC(Multi-Versioning Concurrency Control,多版本併發控制) 03)InnoDB 行級別鎖定 04)Oracle 樣式一致非鎖定讀取 05)表數據進行整理來優化基於主鍵的查詢 06)支持外鍵引用完整性約束 07)大型數據捲上的最大性能 08)將對錶的查詢與不一樣存儲引擎混合 09)出現故障後快速自動恢復 10)用於在內存中緩存數據和索引的緩衝區池  架構
innodb核心特性併發
重點: MVCC 事務 行級鎖 熱備份 Crash Safe Recovery(自動故障恢復)
1)使用 SELECT 確認會話存儲引擎
#查詢默認存儲引擎 mysql> SELECT @@default_storage_engine; +--------------------------+ | @@default_storage_engine | +--------------------------+ | InnoDB | +--------------------------+ 1 row in set (0.00 sec)
2)使用 SHOW 確認每一個表的存儲引擎
#查看錶的存儲引擎 mysql> show create table city\G *************************** 1. row *************************** ... ) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) mysql> show table status like 'city'\G *************************** 1. row *************************** Name: city Engine: InnoDB ...
3)使用 INFORMATION_SCHEMA 確認每一個表的存儲引擎
#查看錶的存儲引擎 mysql> select table_name,engine from information_schema.tables where table_name='city' and table_schema='world'\G *************************** 1. row *************************** table_name: city engine: InnoDB 1 row in set (0.00 sec)
1)在啓動配置文件中設置服務器存儲引擎
#在配置文件的[mysqld]標籤下添加/etc/my.cnf [mysqld] default-storage-engine=innodb
2)使用 SET 命令爲當前客戶機會話設置
#在MySQL命令行中臨時設置 mysql> SET @@storage_engine=myisam; Query OK, 0 rows affected, 1 warning (0.00 sec) #查看 mysql> select @@default_storage_engine; +--------------------------+ | @@default_storage_engine | +--------------------------+ | MyISAM | +--------------------------+ 1 row in set (0.00 sec)
(3)在 CREATE TABLE 語句指定
#建表的時候指定存儲引擎 create table t (i INT) engine = <Storage Engine>; #如:建test1表,指定存儲引擎爲myisam mysql> create table test1(id int) engine=myisam; Query OK, 0 rows affected (0.02 sec)
項目背景:
公司原有的架構:一個展現型的網站,LAMT,MySQL5.1.77版本(MYISAM),50M數據量。
小問題不斷:
如何解決:
1)備份生產庫數據(mysqldump)
[root@db01 test]# mysql -uroot -p1 mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | student4 | | tlbb2 | +----------------+ 2 rows in set (0.00 sec) #測試環境(先簡單創幾個存儲引擎爲myisam) mysql> create table test1(id int) engine=myisam; Query OK, 0 rows affected (0.02 sec) mysql> create table test2(id int) engine=myisam;; Query OK, 0 rows affected (0.00 sec) mysql> create table test3(id int) engine=myisam;; Query OK, 0 rows affected (0.01 sec)
2)準備一個5.6.44版本的新數據庫
#先導庫,準備一個環境 [root@db01 test]# mysqldump -uroot -p1 -B test >/tmp/full.sql
3)對備份數據進行處理(將engine字段替換)
#方法一 [root@db01 ~]# sed -i 's#ENGINE=MyISAM#ENGINE=InnoDB#g' /tmp/full.sql #方法二 [root@db01 ~]# vim /tmp/full.sql :%s#MyISAM#InnoDB#g
4)將修改後的備份恢復到新庫
#方法一 [root@db01 test]# mysql -uroot -p123 -h 10.0.0.52 < /tmp/full.sql
5)應用測試環境鏈接新庫,測試全部功能
#鏈接 [root@db02 ~]# mysql -uroot -p123 #查看存儲引擎 mysql> select @@default_storage_engine; +--------------------------+ | @@default_storage_engine | +--------------------------+ | InnoDB | +--------------------------+ 1 row in set (0.00 sec)
6)停應用,將備份以後的生產庫發生的新變化,補償到新庫 7)應用割接到新數據庫
項目結果:
*解決了」小問題」 *

5.5版本之後出現共享表空間概念
表空間的管理模式的出現是爲了數據庫的存儲更容易擴展
5.6版本中默認的是獨立表空間
1)查看共享表空間
#物理查看 [root@db01 ~]# ll /application/mysql/data/ -rw-rw---- 1 mysql mysql 79691776 Aug 14 16:23 ibdata1 #命令行查看 mysql> show variables like '%path%'; +-----------------------+------------------------------------+ | Variable_name | Value | +-----------------------+------------------------------------+ | innodb_data_file_path | ibdata1:76M;ibdata2:50M:autoextend | | ssl_capath | | | ssl_crlpath | | +-----------------------+------------------------------------+ 3 rows in set (0.00 sec) #查看大小 [root@db01 data]# du -sh ibdata1 76M ibdata1
5.6版本中默認存儲: 1.系統數據 2.undo 3.臨時表
5.7版本中默認會將undo和臨時表獨立出來,5.6版本也能夠獨立,只不過須要在初始化的時候進行配置
2)設置方法
#編輯配置文件 [root@db01 ~]# vim /etc/my.cnf [mysqld] innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend
對於用戶自主建立的表,會採用此種模式,每一個表由一個獨立的表空間進行管理
1)查看獨立表空間
#物理查看 [root@db01 ~]# ll /application/mysql/data/world/ -rw-rw---- 1 mysql mysql 688128 Aug 14 16:23 city.ibd #命令行查看 mysql> show variables like '%per_table%'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | innodb_file_per_table | ON | +-----------------------+-------+ 1 row in set (0.01 sec)
企業案例
在沒有備份數據的狀況下,忽然斷電致使表損壞,打不開數據庫。
1)拷貝庫目錄到新庫中(先準備一個和原表結構同樣的環境)
[root@db01 data]# tar zcf world1.tgz world/ #傳到測試環境 [root@db01 data]# scp world1.tgz 172.16.1.52:/application/mysql/data/ #解壓 [root@db02 data]# tar xf world1.tgz
2)啓動新數據庫
[root@db01 ~]# mysqld_safe --defaults-file=/data/3307/my.cnf &
3)登錄數據庫查看r
#查看 mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | | world | +--------------------+ 5 rows in set (0.00 sec)
4)查詢表中數據
mysql> select * from city; ERROR 1146 (42S02): Table 'world.city' doesn't exist (表不存在)
5)找到之前的表結構在新庫中建立表
mysql> show create table world.city; #刪掉外鍵建立語句 CREATE TABLE `city1` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `Name` char(35) NOT NULL DEFAULT '', `CountryCode` char(3) NOT NULL DEFAULT '', `District` char(20) NOT NULL DEFAULT '', `Population` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`ID`), KEY `CountryCode` (`CountryCode`) #CONSTRAINT `city_ibfk_1` FOREIGN KEY (`CountryCode`) REFERENCES `country` (`Code`) ) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=latin1;
6)刪除表空間文件
#刪除表空間文件 mysql> alter table city1 discard tablespace; #在表的物理結構查看 [root@db02 world]# ll total 1000 -rw-rw---- 1 mysql mysql 8710 Nov 4 10:26 city1.frm -rw-rw---- 1 mysql mysql 8710 Nov 4 10:26 city.frm -rw-rw---- 1 mysql mysql 589824 Nov 4 10:26 city.ibd
7)拷貝舊錶空間文件
[root@db02 world1]# cp city.ibd city1.ibd
8)受權
[root@db01 world]# chown -R mysql.mysql *
9)導入表空間
#查看,會報錯 mysql> select * from city1; #導入表空間 mysql> alter table city_new import tablespace; #再次查看 mysql> select * from city1;
#改表名 mysql> alter table city1 rename city; #再次查看 mysql> show tables; +------------------+ | Tables_in_world1 | +------------------+ | city | | country | | countrylanguage | +------------------+ 3 rows in set (0.00 sec)