一、MySQL的連接建立與權限
寫這些的目的一是記錄下工作這幾年所學,算是成長腳印吧。二是復習一遍,也給自己當筆記看,通篇觀點都屬於個人理解較多。讀者觀看的時候也需要自己判斷下是否正確,另外,記下一段我非常喜歡的話:年少輕狂的我同樣有對未來的迷茫,對生活的憤懣,對社會的厭惡,對世道的鄙夷......在閱盡滄桑的飽覽歲月的人看來,這些也許很幼稚,但這不正是青春的特質嗎?青春既然不能夠被挽留,也不能夠被拒絕,那就用自己的方式去揮霍或者,珍惜。
首先介紹連接方式,mysql可以提供來自網絡的tcp/ip連接和只服務本機localhost的Unix域套接字連接,如果服務器不監聽來自網絡的連接,遠程客戶端連接會報錯,服務器不會收到任何消息。
Tcp/ip:用於跟mysql實例不在同一台機器上的客戶端和本機127.0.0.1連接;注意防火牆的設置,防火牆是否放過mysql的進程,是否屏蔽了mysql的3306端口。 Unix域套接字:它不是一種網絡協議,只用於客戶端和mysql實例在同一台機器上,用localhost訪問。 <1>skip_networking 告訴mysql不要監聽網絡,服務只限於本機localhost訪問,127.0.0.1也不能訪問。如果不需要其他主機連接,最好把這變量打開,防止窮舉密碼攻擊。
<2> bind-address 只監聽某個特定地址的連接,這個參數是指定哪些服務器監聽哪些ip的請求,其他ip就算有權限也連接不上。為了數據的安全,可以考慮讓MySQL只守候在127.0.0.1上,這樣從Internet上就無法直接訪問數據庫了。
1
|
|
1)服務端 只要你安裝啟動了mysql服務,就可以通過mysql服務器主機名稱或ip連接。但是客戶端給mysql服務器傳遞之前,主機名稱一定要轉換成ip,如果此主機名稱不是公共網絡上的主機名稱,必須在hosts表里填寫主機名和其ip對應關系, 否則無法連接。 Mysql服務器本機命令行客戶端:Shell>./mysql –hhost –uuser –ppwd 分別在C:\Windows\System32\drivers\etc\hosts和/etc/hosts中添加:ip hostname,然后分別重新連接,均可正常連接。 【1】resolveip工具 對hostname和ip的轉換工具。位於/usr/local/mysql/bin/。 2)客戶端域名連接授權 此域名對應mysql庫的user表中的host字段,是用來控制對客戶端的連接權限的。 mysql> INSERT INTO `user` VALUES ('ip', 'user', password("pwd"), 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', '0', '0', '0', '0', '', null);//域名授權 mysql> INSERT INTO `user` VALUES ('ip', 'user', password("pwd"), 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', '0', '0', '0', '0', '', null);//ip段授權,在此ip段的客戶端都可以通過hanmm這個賬號連接mysql服務。 or grant 權限 on 數據庫對象 to 用戶@'host' identified by 'pwd' Host cache 選項就能禁用主機緩存。想要清除主機緩存,可以提交 FLUSH HOSTS 語句或者運行 mysqladmin flush-hosts. <1>skip-name-resolve skip-name-resolve能大大加快用戶獲得連接的速度,特別是在網絡情況較差的情況下。MySQL在收到連接請求的時候,會根據請求包中獲得的ip來反向追查請求者的主機名。然后再根據返回的主機名又一次去獲取ip。如果兩次獲得的ip相同,那么連接就成功建立了。在DNS不穩定或者局域網內主機過多的情況下,一次成功的連接將會耗費很多不必要的時間。假如MySQL服務器的ip地址是廣域網的,最好不要設置skip-name-resolve。 When a new thread connects to mysqld, mysqld will spawn a new thread to handle the request. This thread will first check if the hostname is in the host cache. If not the thread will call gethostbyaddr_r() and gethostbyname_r() to resolve the hostname. 當一個新的連接請求產生,mysql會啟動一個新線程去處理此請求,該線程首先會檢查域名緩存里是否有此域名,如果緩存里不存在,則調用gethostbyaddr_r()和gethostbyname_r()處理此域名。 If the operating system doesn't support the above thread-safe calls, the thread will lock a mutex and call gethostbyaddr() and gethostbyname() instead. Note that in this case no other thread can resolve other hostnames that is not in the hostname cache until the first thread is ready. 如果操作系統對這兩個函數不提供線程安全的調用(我理解是每個線程隔離並行),則此線程對操作系統該資源加鎖,然后調用方法,直到它處理完釋放此資源鎖,別的線程才能調用。 You can disable DNS host lookup by starting mysqld with --skip-name-resolve. In this case you can however only use IP names in the MySQL privilege tables. 你可以在啟動時加--skip-name-resolve這個參數,避免DNS host查找過程,這樣你使用ip地址而不能使用域名連接訪問mysql。 If you have a very slow DNS and many hosts, you can get more performance by either disabling DNS lookop with --skip-name-resolve or by increasing the HOST_CACHE_SIZE define (default: 128) and recompile mysqld. 如果DNS服務很慢且有很多域名,想要提高性能,你可選擇加參數--skip-name-resolve啟動,或者增大域名緩存空間大小。 允許域名解析的時候 localhost=127.0.0.1,禁止域名解析之后localhost與127.0.0.1並不是同一個主機。所以在禁止域名解析之后,需要重新設置用戶權限,不能再使用 localhost ,使用 % 任意主機或者IP地址如127.0.0.1 。 You can disable the hostname cache with --skip-host-cache. You can clear the hostname cache with FLUSH HOSTS or mysqladmin flush-hosts. If you don't want to allow connections over TCP/IP, you can do this by starting mysqld with --skip-networking. <2>host_cache_size 5.6.26默認279。The host_cache_size value, introduced in MySQL 5.6.5, is ignored by the server. The host_cache table only holds 128 entries. <3>skip-grant-tables 如果忘記管理員密碼,在啟動mysql時不啟動grant-tables授權表。mysqld_safe --skip-grant-tables & 然后修改管理員密碼: mysql>update user set password=password('yournewpasswordhere') where user='root'; mysql>flush privileges; mysql>exit; 重啟mysql。
<1>socket
默認值是/tmp/mysql.sock,此文件刪除掉會導致socket連接失敗。 Unix平台:用於本地客戶端連接的套接字文件。默認為/var/lib/mysql/mysql.sock。 Windows:用於本地客戶端連接的命名管道名。默認為mysql。 <2>max_connections mysql是多線程的,可以同時接收客戶端的多個連接(connection)請求。max_connections是整個mysql允許的最大並發連接數(實際值比該值多1,預留給系統管理員),影響整個mysql應用的並發處理能力。
只要服務器監聽了網絡tcp連接,不管用戶名密碼對不對,有沒有權限,客戶端發起連接請求,不管三七二十一,先檢查當前連接數是否已達到上限,達到連接上線拒絕連接。一般來說,只要mysql主機性能允許,應該將
該參數設置的盡量大一點,一般1000-5000左右是一個比較合適的參考值。 <3>max_user_connections 每個用戶允許的最大連接數。該參數針對單個用戶的連接限制。 在一般情況下我們很少使用這個限制,只有在一些專門提供mysql數據存儲服務或者提供虛擬主機的應用中可能用到。 <4>connect_timeout 連接超時 檢測方法 telnet ip 3306.連接超時時間,客戶端發送tcp第一次握手,我要請求了;服務器端收到請求,檢查連接未達到上限,返回同意,計時開始;客戶端發送真正的(如select)請求,再到服務器端,
這段時間超過connet_timeout,就斷開了。默認值10,一般不要動。【在數據量大的情況下,由於網絡等原因,如果connect_timeout設置過低,極有可能連接超時。這個值最低好像是2,許允許設置成0,設置成0其實就是
所有連接都連接不上了。】 權限1---連接權限認證: Usage,連接(登陸)權限。建立一個用戶,默認授予這個權限。該權限只能用於數據庫登陸,不能做任何操作。客戶端連接時,傳遞給服務器端的信息:客戶端的hostname或者IP地址、數據庫
服務器的IP地址或域名、數據庫服務的端口號、數據庫帳號名稱、數據庫帳號對應的密碼。服務器端檢查mysql庫的user表是否存在user和password對應用戶,host是否符合對應host,用戶是否有Usage權限。通過身份認證
連接才能建立,否則拒絕連接。客戶端連接成功后取得該鏈接的所有權限,在該連接生命周期內權限不會變,即使在別處更改了權限,也不會影響。例如:該用戶沒有delete權限,在連接后,管理員賦予它delete權限,可是得等
到此連接斷開,下一次連接成功后才能獲得delete權限。 例如: 192.168.1.1服務器上安裝啟動mysql服務。 mysql> INSERT INTO `user` VALUES ('192.168.1.1', 'user', password("pwd"), 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', '0', '0', '0', '0', '', null); User表里host字段是連接客戶端的ip,和mysql服務器主機ip沒有關系,為哪個客戶端賦連接權限,就是哪個客戶端主機的ip。 <5>Aborted_connects 用戶名密碼不對或沒權限或連接超時(connect_timeout),被丟棄的連接數。 <6>max_connect_errors 最大連接失敗數,max_connect_errors默認值為10,如果受信帳號錯誤連接次數達到10則自動堵塞,需要flush hosts來解除。如果你得到象這樣的一個錯誤: Host ’hostname’ is blocked because of many connection errors. Unblock with ’mysqladmin flush-hosts’ 在max_connect_errors次失敗請求后,mysqld認定出錯了(像來自一個黑客的攻擊),並且阻止該站點進一步的連接,直到某人執行命令mysqladmin flush-hosts或者有reload權限的用戶登錄后,執行mysql>flush hosts。 mysql認為是惡意連接,會強制阻止此客戶端連接。當此客戶端有一次連接成功后,針對此客戶端的max_connect_errors會清零。---這個參數沒驗證出來。 <7>thread_stack 每個連接線程被創建的時候,MySQL 給他分配的內存大小。 當 MySQL 創建一個新的連接線程的時候,是需要給他分配一定大小的內存堆棧空間,以便存放 客戶端的請求 Query 以及自身的各種狀態和處理信息。不過一般來說如果不是對 MySQL 的連接線 程處理機制十分熟悉的話,不應該輕易調整該參數的大小,使用系統的默認值(192KB)基本上 可以所有的普通應用環境。如果該值設置太小,會影響 MySQL 連接線程能夠處理客戶端請求的 Query 內容的大小,以及用戶創建的 Procedures 和 Functions 等 <8>back_log 短時間內得到大量連接請求,並且超過max_connections,mysql暫時停止回答新請求之前, 允許被存在堆棧中的請求數量。操作系統的TCP/ip連接的偵聽隊列大小對這個隊列大小有限制, 高於操作系統限制是無效的。
1、Usage權限 連接登陸。新增的用戶默認賦予這個權限,且此usage權限不能被收回。
2、管理grant權限 擁有grant option,就可以將自己擁有的權限授予其他用戶(僅限於自己已經擁有的權限) mysql> grant Grant option on db.* to db@localhost; mysql> grant select on db.* to db@localhost; mysql>grant select *.* to ‘user’@’192.168.1.%’ identified by ‘pwd’;
3、管理權限process 通過這個權限,用戶可以執行SHOW PROCESSLIST和KILL命令。默認情況下,每個用戶都可以執行SHOW PROCESSLIST命令,但是只能查詢本用戶的進程。kill命令殺死服務器線程。你總是能顯示或殺死你自己的線程,
但是你需要PROCESS權限來顯示或殺死其他用戶和SUPER權限啟動的線程。 mysqld為有process權限的用戶保留一個額外的連接, 以便一個MySQL root用戶能登錄並檢查,即使所有的正常連接在使用。所以當連接數達到最大時,普通連接建立不了的時候,擁有process權限的用戶還是可以連接的。 shell>./mysqladmin –uroot –proot restart mysql>kill 3;//殺死id=3的進程。
4、管理權限file 擁有file權限才可以執行 select ..into outfile和load data infile…操作,但是不要把file, process, super權限授予管理員以外的賬號,這樣存在嚴重的安全隱患。 管理權限(如 super, process, file等)不能夠指定某個數據庫,on后面必須跟*.*。 mysql> grant file on *.* to db@localhost; mysql> load data infile ‘/home/mysql/db.txt’ into table db;
5、管理權限super 這個權限允許用戶終止任何查詢;修改全局變量的SET語句;使用CHANGE MASTER,PURGE MASTER LOGS。修改存儲過程需要super權限(): mysql> grant super on *.* to 'ld'@'ip'; mysql> purge master logs before ‘mysql-bin.000006′; 管理權限(如 super, process, file等)不能夠指定某個數據庫,on后面必須跟*.*。
6、管理權限Shutdown shell>./mysqladmin –hip –uld –pld shutdown
7、管理權限replication slave 擁有此權限可以查看從服務器,從主服務器讀取二進制日志。 mysql> grant replication slave on *.* to 1d@localhost; mysql> show slave hosts; mysql>show binlog events;
8、 replication client 此權限可以查詢master server、slave server狀態。 mysql> grant Replication client on *.* to ld@localhost; 或:mysql> grant super on *.* to ld@localhost; mysql> show master status;
9、Reload權限 必須擁有reload權限,才可以執行 flush-hosts, flush-logs, flush-privileges, flush-status, flush-tables, flush-threads, refresh, reload命令。 MySQL的FLUSH句法,用於清除或者重新加載內部緩存。而使用flush語句,你必須有reload權限。 (1)flush hosts 清空hostname cache,hostname cache與連接時skip-name-resolve有關。 Flush logs: 關閉當前的二進制日志文件並創建一個新文件,新的二進制日志文件的名字在當前的二進制文件的編號上加1。 (2)flush logs 關閉當前的二進制日志文件並創建一個新文件,新的二進制日志文件的名字在當前的二進制文件的編號上加1。 (3)flush privileges 這個也是經常使用的,每當重新賦權后,為了以防萬一,讓新權限立即生效,一般都執行一把,目地是從數據庫授權表中重新裝載權限到緩存中。 (4)flush tables 關閉所有打開的表,同時該操作將會清空查詢緩存中的內容。
(5)flush tables with read lock 關閉所有打開的表,同時對於所有數據庫中的表都加一個讀鎖,直到顯示地執行unlock tables,該操作常常用於數據備份的時候。 (6)flush STATUS 重置大多數狀態變量到0。 (7)flush MASTER 刪除所有的二進制日志索引文件中的二進制日志文件,重置二進制日志文件的索引文件為空,創建一個新的二進制日志文件,不過這個已經不推薦使用,改成reset master 了。
(8)flush QUERY CACHE 重整查詢緩存,消除其中的碎片,提高性能,但是並不影響查詢緩存中現有的數據,這點和Flush table 和Reset Query Cache(將會清空查詢緩存的內容)不一樣的。 (9)flush slave 類似於重置復制吧,讓從數據庫忘記主數據庫的復制位置,同時也會刪除已經下載下來的relay log,與Master一樣,已經不推薦使用,改成Reset Slave了。這個也很有用的。 一般來講,Flush操作都會記錄在二進制日志文件中,但是FLUSH LOGS、FLUSH MASTER、FLUSH SLAVE、FLUSH TABLES WITH READ LOCK不會記錄,因此上述操作如果記錄在二進制日志文件中話,
會對從數據庫造成影響。注意:Reset操作其實扮演的是一個Flush操作的增強版的角色。 (10) references 有了REFERENCES權限,用戶就可以將其它表的一個字段作為某一個表的外鍵約束。 11、 lock tables 必須擁有lock tables權限,才可以使用lock tables mysql> grant lock tables on ld.* to p1@localhost; mysql> lock tables a1 read; mysql> unlock tables;。 12、show view 必須擁有show view權限,才能執行show create view。 mysql> grant show view on ld.* to ld@localhost; mysql> show create view v_shop; 13、show database 通過show database只能看到你擁有的某些權限的數據庫,除非你擁有全局SHOW DATABASES權限。 對於ld@localhost用戶來說,沒有對mysql數據庫的權限,所以以此身份登陸查詢時,無法看到mysql數據庫: mysql> show databases; <1>skip_show_database 防止不具有SHOW DATABASES權限的人們使用SHOW DATABASES語句。如果你擔心用戶能夠看見屬於其它用戶的數據庫,這樣設置可以提高安全性。其效果取決於SHOW DATABASES權限:如果變量值為ON,只允許具有SHOW DATABASES權限的人們使用SHOW DATABASES 語句,並且該語句將顯示所有數據庫名。如果值為OFF,允許所有用戶執行SHOW DATABASES,但只顯示用戶具有SHOW DATABASES或其它權限的數據庫的名稱。 14. excute 查看並執行存在的Functions,Procedures的權限。 mysql> grant execute on ld.* to 'ld'@'192.168.1.1' identified by 'ld'; 查看並執行存儲過程的權限。例如:執行完這句ld用戶就可以查看到ld庫中的存儲過程名字,但打開啥也沒有,也能執行,但是不能修改。 mysql> call pro_shop1(0001,@a); mysql> select @a; 15、alter routine權限 必須具有alter routine的權限,才可以使用{alter |drop} {procedure|function} mysql> grant alter routine on ld.* to 'ld'@'%' identified by 'ld'; mysql> drop procedure pro_shop; 16、create routine 創建存儲過程或函數。 mysql> grant create routine on zz4.* to 'ld'@'%' identified by 'ld';//賦予權限 mysql> revoke create routine on zz4.* from 'ld'@'%' identified by 'ld';//收回權限 只賦予create routine權限后,修改存儲過程,報錯 mysql> grant select on ld.* from 'ld'@'192.168.1.1' identified by 'ld'; mysql> grant select routine on ld.* from '*'@'192.168.1.1' identified by 'ld'; 17. create temporary tables (注意這里是tables,不是table) 必須有create temporary tables的權限,才可以使用create temporary tables. mysql> grant create temporary tables on ld.* to ‘ld′@’localhost’; [mysql@mydev ~]$ mysql -h localhost -u ld -p ld mysql> create temporary table tt1(id int); 18. create view 必須有create view的權限,才可以使用create view mysql> grant create view on ld.* to ‘ld′@’localhost’; mysql> create view v_shop as select price from shop; 19. create user 要使用CREATE USER,必須擁有mysql數據庫的全局CREATE USER權限,或擁有INSERT權限。 mysql> grant create user on *.* to ‘ld′@’localhost’; 或:mysql> grant insert on *.* to ld@localhost; 20. index 必須擁有index權限,才能執行[create |drop] index 21、create權限 數據庫、表或索引. 必須有create的權限,才可以使用create table mysql> grant create on ld.* to ‘ld′@’localhost’; 22、insert權限 23、drop權限 24、delete權限 25、alter 修改表結構、數據庫屬性、存儲過程。 26、update權限、 27、Select權限 查找數據庫、表或索引。 mysql> select * from cat; 另外,連接后,查詢只顯示有權限的庫和表和字段,新建的用戶默認有Usage權限,和test庫的訪問權限,可以對它查詢,修改,刪除等。權限補充:
【1】proxy user
Mysql偽裝用戶,自從MySQL 5.5 發布第一個版本以來,就在GRANT權限列表里面新增加了一條記錄: PROXY。 不要以為這個是以前的MySQL Proxy 哦。其實這個是用來給用戶做馬甲用的。
偽裝用戶方法:
步驟1:
mysql> select version();//確保版本是5.5以上
步驟2:
mysql> select * from mysql.plugin; //檢查是否已經加載test_plugin_server插件,默認5.5和5.6版本的mysql,都沒有安裝。
+--------------------+----------------------+
| name | dl |
+--------------------+----------------------+
| test_plugin_server | auth_test_plugin.dll |
+--------------------+----------------------+
步驟3:
//如果沒有安裝插件,執行這句安裝;
mysql> install plugin test_plugin_server soname 'auth_test_plugin.dll';
步驟4:
mysql> create user 'pp_ext'@'%' identified with test_plugin_server as 'pp';
步驟5:
mysql> grant proxy on 'pp'@'%' to 'pp_ext'@'%';
步驟6:
mysql> flush privileges;
步驟7:
退出,用用戶名pp_ext密碼:pp登陸。
報錯:
1251-Client does not support authentication protocol requested by server;consider upgrading MySQL client
@@proxy_user 這個只讀變量為NULL。沒有偽裝成功。得升級客戶端版本。我用的是navicat.
更新完客戶端后,查看一下偽裝用戶的權限
Mysql>show grants for ‘pp’@’%’;
操作更正常用戶沒什么區別。
<1> proxy_user
【2】Mysqlaccess命令
用戶權限檢查程序
【3】mysql_setpermission
用於管理用戶權限信息的交互式perl腳本。