马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?开始注册
x
执行导出数据库:) R' d! }; Z8 f3 x) `
mysqldump -u root -predh3 nova >/root/zhongnan-nova.sql
C: \ N9 a7 S$ J! G/ xmysqldump: Got error: 1033: "Incorrect information in file: './nova/agent_builds.frm'" when using LOCK TABLES4 E* G) W) X$ T+ M3 c* d( A
报错了:; f9 J5 P0 b; E9 f& f8 y8 Z5 \
Got error: 1033:
1 i* @) e2 A3 ^! Mwhen using LOCK TABLES
! [& \/ f; e0 }, ^8 P+ O5 d3 X解决方法授予用户锁表权限即可。 网上有人说使用 –skip-lock-tables,这个会影响数据的一致性(可能比丢数据还要遭糕),故不推荐使用这个方法。 –single-transaction 用于 Innodb 引擎的数据库 dump 时,可以不锁表。 mysql 锁表原理深入下去还有很多细节可以学习,可以参考 Ref 相关资料。 导数据库报上面错,添加参数--single-transaction % R. `& T# x! K" Y
[root@compute03 ~]# mysqldump -u root -predh3 nova --single-transaction >/root/zhongnan-nova.sql
( F( }: t* a) Emysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)- C: P2 E$ s0 ^; f
. r. S/ |: w2 _# \8 b
还是报错::1 O: L* v/ u8 G* a8 r2 T' I5 i
登录到数据库中show
8 n2 k3 \* q. @: r! c1 BMariaDB [nova]> show create table `agent_builds` ;% J1 `9 J& W. S$ \1 e; z/ e
ERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'
: C \7 a; i% n查看数据结构:$ h5 L; V5 j) K! q4 H3 Z- d
MariaDB [nova]> desc agent_builds;9 G8 A, D1 N* g9 D( [
ERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'* R# C+ j; J; s5 O+ N
3 m8 t2 D" v2 f% C7 |6 F# troot@compute03 ~]# mysqldump -u root -predhat123 nova --single-transaction --skip-lock-tables >/root/zhongnan-nova.sql
8 F% G" V) \4 ^% m# [3 G' Nmysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)6 M! L6 A1 a& x" o
( ~& p! z$ _! [' I. G% }
1 F) Q$ r/ n. D2 _) |' E
今天在备份一位客户的mysql数据库的时候,使用mysqldump命令备份,出现when using LOCK TABLES的提示。如果对mysql中的用户的权限进行过详细设置的话,会知道用户可以被分配LOCK TABLES和UNLOCK TABLES两个权限,使该用户在对该用户的表进行读写锁设定。
j# ^2 a' a$ N' i8 R8 [ 遇到该问题,解决方案如下:
: y: t$ R7 G) z( V7 w 在执行备份的时候,将命令中添加 --skip-lock-tables,即命令如下:1 T" |8 K$ [) l5 U
mysqldump -u 用户名 -p 用户密码 --skip-lock-tables -R database > /root/database_1120.dmp0 Q2 i8 s. e1 ?
: q @( E% X b# N, ?% Y
下面是对事务表使用LOCK TABLES的说明:/ ~# S4 ^, o4 J( _5 [
在尝试锁定表之前,LOCK TABLES不是事务安全型的,会隐含地提交所有活性事务。同时,开始一项事务(例如,使用START TRANSACTION),会隐含地执行UNLOCK TABLES4 n' B5 C- d8 p" j
对事务表(如InnoDB)使用LOCK TABLES的正确方法是,设置AUTOCOMMIT=0并且不能调用UNLOCK TABLES,直到您明确地提交事务为止。当您调用LOCK TABLES时,InnoDB会内部地取其自己的表锁定,MySQL取其自己的表锁定。InnoDB在下一个提交时释放其表锁定,但是,对于MySQL,要释放表锁定,您必须调用UNLOCK TABLES。您不应该让AUTOCOMMIT=1,因为那样的话,InnoDB会在调用LOCK TABLES之后立刻释放表锁定,并且很容易形成死锁定。注意,如果AUTOCOMMIT=1,我们根本不能获取InnoDB表锁定,这样就可以帮助旧的应用软件避免不必要的死锁定。; Y5 j0 P/ H0 ~4 _5 j
ROLLBACK不会释放MySQL的非事务表锁定。% E- d: q: i5 x
要使用LOCK TABLES,您必须拥有相关表的LOCK TABLES权限和SELECT权限。
/ u6 F0 R, _: G; v 使用LOCK TABLES的主要原因是仿效事务,或在更新表时加快速度。这将在后面进行更详细的解释。
- j. J1 ^) ]4 F. A0 e5 P1 v如果一个线程获得对一个表地READ锁定,该线程(和所有其它线程)只能从该表中读取。如果一个线程获得对一个表的WRITE锁定,只有保持锁定的线程可以对表进行写入。其它的线程被阻止,直到锁定被释放时为止。
" v/ a, U& T' R3 TREAD LOCAL和READ之间的区别是,READ LOCAL允许在锁定被保持时,执行非冲突性INSERT语句(同时插入)。但是,如果您正打算在MySQL外面操作数据库文件,同时您保持锁定,则不能使用READ LOCAL。对于InnoDB表,READ LOCAL与READ相同。. U9 f0 J1 b& V
当您使用LOCK TABLES时,您必须锁定您打算在查询中使用的所有的表。虽然使用LOCK TABLES语句获得的锁定仍然有效,但是您不能访问没有被此语句锁定的任何的表。同时,您不能在一次查询中多次使用一个已锁定的表——使用别名代替,在此情况下,您必须分别获得对每个别名的锁定。% j( L6 ` ]4 A6 Q( i/ W) }
mysql> LOCK TABLE t WRITE, t AS t1 WRITE;* q: ]! \0 h M3 a5 K6 V
$ U H5 x7 e2 y7 \/ n$ l" ^mysql> INSERT INTO t SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES' D7 {2 t: M2 s' W6 p4 p
% k0 w; k) C! J1 J8 t" G
mysql> INSERT INTO t SELECT * FROM t AS t1; 如果您的查询使用一个别名引用一个表,那么您必须使用同样的别名锁定该表。如果没有指定别名,则不会锁定该表。4 Z# |; y- Y, ?) L n6 }
mysql> LOCK TABLE t READ;- u6 }. C2 P( X) q) Y
# K7 `/ O; o) B5 E
mysql> SELECT * FROM t AS myalias;ERROR 1100: Table 'myalias' was not locked with LOCK TABLES相反的,如果您使用一个别名锁定一个表,您必须使用该别名在您的查询中引用该表。" R. S- L: R* z! }( w
mysql> LOCK TABLE t AS myalias READ;4 n9 t+ F0 i" K+ S5 R& f) b) O& ^8 \% D
$ F, H o% ^4 q! `
mysql> SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES
4 |' `( u. A% U" }, D
, L5 B" V- A" |. a: d' @- `. l6 Jmysql> SELECT * FROM t AS myalias;8 J* t4 y' i2 b
WRITE锁定通常比READ锁定拥有更高的优先权,以确保更新被尽快地处理。这意味着,如果一个线程获得了一个READ锁定,则另一个线程会申请一个WRITE锁定,后续的READ锁定申请会等待,直到WRITE线程获得锁定并释放锁定。您可以使用LOW_PRIORITY WRITE锁定来允许其它线程在该线程正在等待WRITE锁定时获得READ锁定。只有当您确定最终将有一个时机,此时没有线程拥有READ锁定时,您才应该使用LOW_PRIORITY WRITE锁定。" {7 M6 q( d. [& _' u' j5 U9 L
LOCK TABLES按照如下方式执行:
6 i! F9 |$ ^/ Z4 |1. 按照内部定义的顺序,对所有要被锁定的表进行分类。从用户的角度,此顺序是未经定义的。
3 E9 u" X* _9 f0 c/ c2. 如果使用一个读取和一个写入锁定对一个表进行锁定,则把写入锁定放在读取锁定之前。
1 c1 j [4 L4 |3 S; V% a5 M3. 一次锁定一个表,直到线程得到所有锁定为止。2 k K% u3 a- V
该规则确保表锁定不会出现死锁定。但是,对于该规则,您需要注意其它的事情:
j0 R5 f2 i! V. x* [如果您正在对一个表使用一个LOW_PRIORITY WRITE锁定,这只意味着,MySQL等待特定的锁定,直到没有申请READ锁定的线程时为止。当线程已经获得WRITE锁定,并正在等待得到锁定表清单中的用于下一个表的锁定时,所有其它线程会等待WRITE锁定被释放。如果这成为对于应用程序的严重的问题,则您应该考虑把部分表转化为事务安全型表。& ^9 |- s" h2 ?& Y* |
您可以安全地使用KILL来结束一个正在等待表锁定的线程。6 \5 t: t& `! R1 M* k D6 j9 X
注意,您不能使用INSERT DELAYED锁定任何您正在使用的表,因为,在这种情况下,INSERT由另一个线程执行。
1 w7 z9 {* ^ o' T( \通常,您不需要锁定表,因为所有的单个UPDATE语句都是原子性的;没有其它的线程可以干扰任何其它当前正在执行的SQL语句。但是,在几种情况下,锁定表会有好处:1 E4 A" y( p9 e" c% Z0 M# l
如果您正在对一组MyISAM表运行许多操作,锁定您正在使用的表,可以快很多。锁定MyISAM表可以加快插入、更新或删除的速度。不利方面是,没有线程可以更新一个用READ锁定的表(包括保持锁定的表),也没有线程可以访问用WRITE锁定的表(除了保持锁定的表以外)。
^3 M3 a7 a8 p! w有些MyISAM操作在LOCK TABLES之下更快的原因是,MySQL不会清空用于已锁定表的关键缓存,直到UNLOCK TABLE被调用为止。通常,关键缓存在每个SQL语句之后被清空。6 ]; E/ C; [0 e* Q: W: k6 u' L
如果您正在使用MySQL中的一个不支持事务的存储引擎,则如果您想要确定在SELECT和UPDATE之间没有其它线程,您必须使用LOCK TABLES。本处所示的例子要求LOCK TABLES,以便安全地执行:
0 ]( L+ @. `( ^6 Q6 s mysql> LOCK TABLES trans READ, customer WRITE;·
5 X8 t# w0 b1 y7 [+ v: c* t- x/ o" a( M
mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;·
" `. z9 C& U' ?/ ?3 Y" V8 I9 t- i& z/ q* a0 u3 P# H, A* `
mysql> UPDATE customer·
% K2 S% W) @& [% F b; ?-> SET total_value=sum_from_previous_statement·
$ ?/ M# U4 x- T, V" ]# H -> WHERE customer_id=some_id;·
& k) }3 K: Q" C- N) O: s, @0 z. n( O% E
mysql> UNLOCK TABLES;如果没有LOCK TABLES,有可能另一个线程会在执行SELECT和UPDATE语句之间在trans表中插入一个新行。8 p0 A8 B1 [! L3 T$ U) v. [% _
通过使用相对更新(UPDATE customer SET value=value+new_value)或LAST_INSERT_ID()函数,您可以在许多情况下避免使用LOCK TABLES。
4 t% `5 V& o. T9 u( E V; J通过使用用户层级的顾问式锁定函数GET_LOCK()和RELEASE_LOCK(),您也可以在有些情况下避免锁定表。这些锁定被保存在服务器中的一个混编表中,使用pthread_mutex_lock() 和pthread_mutex_unlock(),以加快速度。8 t; p; T; C: n/ v+ }1 e4 ~
要了解更多有关锁定规则的说明
4 s4 o) q6 f) N8 x/ l+ b您可以使用FLUSH TABLES WITH READ LOCK语句锁定位于所有带有读取锁定的数据库中的所有表。如果您有一个可以及时拍摄快照的文件系统,比如Veritas,这是获得备份的一个非常方便的方式。
' R U' p1 d9 H1 H5 |9 A* V注释:如果您对一个已锁定的表使用ALTER TABLE,该表可能会解锁。
1 E4 Q5 H( U9 H! M# }6 G1 j' I' N1 K: C
+ \: c; C6 X r
: a8 Z' v: W$ F( B/ w0 R4 f在一个网站上看到一个解决方法:
' d; l4 W4 Z' c' |, t1.创建一个暂存鱼眼/坩埚服务器$ o5 m3 Q1 p- P
2.连接到另一个MySQL数据库服务器/ V3 V3 A7 D P! I1 L
3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件
6 J/ p# O. z. U4.重启Fisheye/Crucible生产服务器
: q0 l* T ^- c; @* {1 R* l' t0 }; j' B
* Y) h8 h! f; l4 t- Z5 m
|