<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:wfw="http://wellformedweb.org/CommentAPI/">
<channel>
<title>dwt&#039;s life - mysql</title>
<link>https://dwt.life/tag/mysql/</link>
<atom:link href="https://dwt.life/feed/tag/mysql/" rel="self" type="application/rss+xml" />
<language>zh-CN</language>
<description></description>
<lastBuildDate>Tue, 20 Jun 2023 19:30:49 +0800</lastBuildDate>
<pubDate>Tue, 20 Jun 2023 19:30:49 +0800</pubDate>
<item>
<title>【转载】MySql 外键约束 之CASCADE、SET NULL、RESTRICT、NO ACTION分析和作用</title>
<link>https://dwt.life/archives/333/</link>
<guid>https://dwt.life/archives/333/</guid>
<pubDate>Tue, 20 Jun 2023 19:30:49 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[https://www.cnblogs.com/yzuzhang/p/5174720.htmlMySQL有两种常用的引擎类型：MyISAM和InnoDB。目前只有InnoDB引擎类型支持外键约束...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p><a href="https://www.cnblogs.com/yzuzhang/p/5174720.html">https://www.cnblogs.com/yzuzhang/p/5174720.html</a></p><p>MySQL有两种常用的引擎类型：MyISAM和InnoDB。目前只有InnoDB引擎类型支持外键约束。InnoDB中外键约束定义的语法如下：</p><pre><code>ALTER TABLE tbl_name
    ADD [CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]</code></pre><p>例如：</p><pre><code>ALTER TABLE `user_resource` CONSTRAINT `FKEEAF1E02D82D57F9` FOREIGN KEY (`user_Id`) REFERENCES `sys_user` (`Id`)</code></pre><p>InnoDB也支持使用ALTER TABLE来删除外键：</p><p>ALTER TABLE <code>user_resource</code> DROP FOREIGN KEY <code>FKEEAF1E02D82D57F9</code>;</p><p><em>CASCADE</em><br>在父表上update/delete记录时，同步update/delete掉子表的匹配记录 </p><p><em>SET NULL</em><br>在父表上update/delete记录时，将子表上匹配记录的列设为null (要注意子表的外键列不能为not null)  </p><p><em>NO ACTION</em><br>如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作  </p><p><em>RESTRICT</em><br>同no action, 都是立即检查外键约束</p><p><em>SET NULL</em><br>父表有变更时,子表将外键列设置成一个默认的值 但Innodb不能识别</p><p>NULL、RESTRICT、NO ACTION<br>删除：从表记录不存在时，主表才可以删除。删除从表，主表不变<br>更新：从表记录不存在时，主表才可以更新。更新从表，主表不变</p><p>CASCADE<br>删除：删除主表时自动删除从表。删除从表，主表不变<br>更新：更新主表时自动更新从表。更新从表，主表不变</p><p>SET NULL<br>删除：删除主表时自动更新从表值为NULL。删除从表，主表不变<br>更新：更新主表时自动更新从表值为NULL。更新从表，主表不变</p><p>外键约束属性： RESTRICT | CASCADE | SET NULL | NO ACTION  外键的使用需要满足下列的条件：</p><ol><li>两张表必须都是InnoDB表，并且它们没有临时表。</li><li>建立外键关系的对应列必须具有相似的InnoDB内部数据类型。</li><li>建立外键关系的对应列必须建立了索引。</li><li>假如显式的给出了CONSTRAINT symbol，那symbol在数据库中必须是唯一的。假如没有显式的给出，InnoDB会自动的创建。</li></ol><p>如果子表试图创建一个在父表中不存在的外键值，InnoDB会拒绝任何INSERT或UPDATE操作。如果父表试图UPDATE或者DELETE任何子 表中存在或匹配的外键值，最终动作取决于外键约束定义中的ON UPDATE和ON DELETE选项。InnoDB支持5种不同的动作，如果没有指定ON DELETE或者ON UPDATE，默认的动作为RESTRICT:</p><ol><li>CASCADE: 从父表中删除或更新对应的行，同时自动的删除或更新自表中匹配的行。ON DELETE CANSCADE和ON UPDATE CANSCADE都被InnoDB所支持。</li><li>SET NULL: 从父表中删除或更新对应的行，同时将子表中的外键列设为空。注意，这些在外键列没有被设为NOT NULL时才有效。ON DELETE SET NULL和ON UPDATE SET SET NULL都被InnoDB所支持。</li><li>NO ACTION: InnoDB拒绝删除或者更新父表。</li><li>RESTRICT: 拒绝删除或者更新父表。指定RESTRICT（或者NO ACTION）和忽略ON DELETE或者ON UPDATE选项的效果是一样的。</li><li>SET DEFAULT: InnoDB目前不支持。</li></ol><p>外键约束使用最多的两种情况无外乎：</p><p>1）父表更新时子表也更新，父表删除时如果子表有匹配的项，删除失败；</p><p>2）父表更新时子表也更新，父表删除时子表匹配的项也删除。</p><p>前一种情况，在外键定义中，我们使用ON UPDATE CASCADE ON DELETE RESTRICT；后一种情况，可以使用ON UPDATE CASCADE ON DELETE CASCADE。</p><p>当执行外键检查之时，InnoDB对它照看着的子或父记录设置共享的行级锁。InnoDB立即检查外键约束，检查不对事务提交延迟。</p><p>要使得对有外键关系的表重新载入转储文件变得更容易，mysqldump自动在转储输出中包括一个语句设置FOREIGN_KEY_CHECKS为0。这避免在转储被重新装载之时，与不得不被以特别顺序重新装载的表相关的问题。也可以手动设置这个变量：</p><pre><code>mysql&gt; SET FOREIGN_KEY_CHECKS = 0;

mysql&gt; SOURCE dump_file_name;

mysql&gt; SET FOREIGN_KEY_CHECKS = 1;</code></pre><p>　　如果转储文件包含对外键是不正确顺序的表，这就以任何顺序导入该表。这样也加快导入操作。设置FOREIGN_KEY_CHECKS为0，对于在LOAD DATA和ALTER TABLE操作中忽略外键限制也是非常有用的。</p><p>InnoDB不允许你删除一个被FOREIGN KEY表约束引用的表，除非你做设置SET FOREIGN_KEY_CHECKS=0。当你移除一个表的时候，在它的创建语句里定义的约束也被移除。</p><p>　　如果你重新创建一个被移除的表，它必须有一个遵从于也引用它的外键约束的定义。它必须有正确的列名和类型，并且如前所述，它必须对被引用的键有索引。如果这些不被满足，MySQL返回错误号1005 并在错误信息字符串中指向errno 150。</p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/333/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/mysql/</wfw:commentRss>
</item>
<item>
<title>MySQL 主从恢复记录</title>
<link>https://dwt.life/archives/316/</link>
<guid>https://dwt.life/archives/316/</guid>
<pubDate>Tue, 15 Nov 2022 03:21:01 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[流程过程大致如下：从主库找到备份文件，放到从库服务器。恢复数据到从库设置MySQL还原点启动从库开始主从复制连接数据库先连接主库mysql -uroot -p切换数据库（或者不切换也行）    ...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<h2>流程</h2><p>过程大致如下：</p><ul><li>从主库找到备份文件，放到从库服务器。</li><li>恢复数据到从库</li><li>设置MySQL还原点</li><li>启动从库开始主从复制</li></ul><h3>连接数据库</h3><p>先连接主库<br><code>mysql -uroot -p</code></p><h3>切换数据库（或者不切换也行）</h3><p><code>    use yourdatabase;</code></p><h3>停止主从复制</h3><pre><code class="lang-sql">stop slave;
reset slave all;</code></pre><h3>设置写入缓存大小。提高mysql导入速度。(和磁盘IO差不多就行)</h3><p><code>set global bulk_insert_buffer_size=128*1024*1024;</code></p><h3>恢复数据 （根据自己的备份方式恢复）</h3><p><code>source /bakfile</code></p><h3>找到mysql binlog 备份点 （在linux 下面执行，其他操作系统同理）</h3><pre><code class="lang-shell">less  /bakfile </code></pre><p>找到</p><pre><code>-- CHANGE MASTER TO MASTER_LOG_FILE=&#039;mysql-bin-190.000640&#039;, MASTER_LOG_POS=120;
/*获取时间binlog文件名和pos*/</code></pre><p>注意，实际可能并不需要这样，直接在主库执行：<br><code>show master status</code><br><a href="https://i.peo.pw/2022/11/15/637294db240f2.png"><img src="https://i.peo.pw/2022/11/15/637294db240f2.png" alt="1668453592882.png" title="1668453592882.png"></a><br>取得了bin-log和pos后直接修改从库，pos其实可以为0，会自动follow。</p><h3>修改从库同步位置</h3><pre><code class="lang-sql">CHANGE MASTER TO 
MASTER_HOST=&#039;10.251.192.18&#039;, 
MASTER_USER=&#039;sync&#039;, 
MASTER_PASSWORD=&#039;DBect98773!_sync&#039;, 
MASTER_PORT=3306,
MASTER_LOG_FILE=&#039;mysql-bin-190.000640&#039;,
MASTER_LOG_POS=120;</code></pre><h3>修改缓存。启动复制</h3><pre><code class="lang-sql">set global bulk_insert_buffer_size=8*1024*1024;
start slave ;</code></pre><h3>查看主从同步状态</h3><p><code>show slave status \G;</code></p><h3>如果有问题。查看mysql 错误日志。</h3><h3>同步开始后可能会有少量的冲突出现 ，使用下面语句可以跳过一个事务并查看同步状态</h3><pre><code class="lang-sql">stop slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1 ;
start slave ;
show slave status \G;</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/316/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/mysql/</wfw:commentRss>
</item>
<item>
<title>ActiveCMS数据库批量开启state和city</title>
<link>https://dwt.life/archives/271/</link>
<guid>https://dwt.life/archives/271/</guid>
<pubDate>Wed, 24 Aug 2022 21:52:27 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[UPDATE `states` SET `status`=1 where country_id = 13UPDATE `cities` as city join states state on ...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<pre><code>UPDATE `states` SET `status`=1 where country_id = 13</code></pre><pre><code>UPDATE `cities` as city join states state on city.state_id = state.id SET city.`status`=1 where state.country_id = 13</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/271/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/mysql/</wfw:commentRss>
</item>
<item>
<title>记录一次Mysql主从以及高可用操作【未完待续】</title>
<link>https://dwt.life/archives/195/</link>
<guid>https://dwt.life/archives/195/</guid>
<pubDate>Wed, 09 Mar 2022 17:26:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[之前托管的物理机组的Raid5出现了一块坏盘，介于最近的事情较多，暂时不打算对其做替换，不管硬盘是否可靠，数据备份也是必要的。之前本来是有做计划任务备份的，但是使用的宝塔面板并不支持排除某个数据...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>之前托管的物理机组的Raid5出现了一块坏盘，介于最近的事情较多，暂时不打算对其做替换，<br>不管硬盘是否可靠，数据备份也是必要的。之前本来是有做计划任务备份的，但是使用的宝塔面板并不支持排除某个数据库，只能选择所有，我有个裤子达到了60G，也懒得去修改宝塔自带的计划任务。因为出现事故第一时间是恢复业务，然而备份只能说是second choice，后续可能会对其进行修改来实现排除某些个数据库的功能。<br>之前也做过主从，这次针对相关服务基于ipvs实现HA。</p><h1>拷贝数据</h1><h2>用户添加</h2><pre><code>grant replication slave on *.* to &#039;rep&#039;@&#039;81.69.%&#039; identified by &#039;123&#039;;
grant replication slave on *.* to &#039;rep&#039;@&#039;81.69.%&#039; identified by &#039;123&#039;;</code></pre><h2>刷新并锁库</h2><pre><code>flush tables with read lock;
show master status;</code></pre><p><img src="https://pic.8oh.com.cn/cos/2022/03/09/7b2a845b03a13_1646815909.png" alt="185.png" title="185.png"></p><p>File的值是当前使用的二进制日志的文件名，Position是该日志里面的位置信息（不需要纠结这个究竟代表什么），记住这两个值，会在下面配置从服务器时用到。</p><p>注意：如果之前的服务器并没有配置使用二进制日志，那么使用上面的sql语句会显示空，在锁表之后，再导出数据库里的数据（如果数据库里没有数据，可以忽略这一步）</p><h2>导出数据</h2><pre><code>mysqldump -uroot -p&#039;123456&#039; -S /tmp/mysql.sock --all-databases &gt; /www/server/backup/mysql_bak.$(date +%F).sql</code></pre><p>这里<code>--all-databases</code>会导出所有库，实际上我们并不希望如此，可使用xargs实现过滤。</p><pre><code>mysql -S /tmp/mysql.sock -uroot -p&#039;123456&#039; -e &quot;show databases;&quot; | grep -Ev &quot;Database|information_schema|mysql|test&quot; | xargs mysqldump -uroot -p&#039;123456&#039; --databases &gt; /www/server/backup/mysql_bak.$(date +%F).sql</code></pre><p>如果数据量很大，可以在导出时就压缩为原来的大概三分之一</p><pre><code>mysql -S /tmp/mysql.sock -uroot -p&#039;123456&#039; -e &quot;show databases;&quot; -uroot -p| grep -Ev &quot;Database|information_schema|mysql|test&quot; | xargs mysqldump -uroot -p&#039;123456&#039; --databases | gzip &gt; /www/server/backup/mysql_bak.$(date +%F).sql</code></pre><p>这时可以对数据库解锁，恢复对主数据库的操作</p><p><code>unlock tables;</code></p><h1>配置主服务器</h1><pre><code>[mysqld]

log-bin=mysql-bin
skip-slave-start
server-id=1
binlog-ignore-db=test
# 不记录某个库的binlog</code></pre><p>注意上面的log-bin和server-id的值都是可以改为其他值的，如果没有上面的配置，首先关闭mysql服务器，然后添加上去，接着重启服务器</p><h1>配置从服务器</h1><p>首先检查从服务器上的my.cnf文件中是否已经在[mysqld]模块下配置server-id</p><pre><code>[mysqld]

server-id=2
replicate-ignore-db=test
replicate-wild-do-table=test.%
# 忽略某些库</code></pre><p>注意上面的server-id的值都是可以改为其他值的（建议更改为ip地址的最后一个字段），如果没有上面的配置，首先关闭mysql服务器，然后添加上去，接着重启服务器</p><p>如果有多个从服务器上，那么每个服务器上配置的server-id都必须不一致。从服务器上没必要配置log-bin，当然也可以配置log-bin选项，因为可以在从服务器上进行数据备份和灾难恢复，或者某一天让这个从服务器变成一个主服务器</p><p>如果主服务器导出了数据，下面就导入该文件，如果主服务器没有数据，就忽略这一步</p><p>[root@localhost ~]# mysql -uroot -p'123456' -S /tmp/mysql.sock &lt; /server/backup/mysql_bak.2022-03-09.sql<br>如果从主服务器上拿过来的是压缩文件，就先解压再导入</p><p>配置同步参数，登陆mysql，输入如下信息：</p><pre><code>mysql&gt; CHANGE MASTER TO
MASTER_HOST=&#039;ip地址&#039;,
MASTER_USER=&#039;rep&#039;,
MASTER_PASSWORD=&#039;rep密码&#039;,
MASTER_LOG_FILE=&#039;mysql-bin.000019&#039;,
MASTER_LOG_POS=120;</code></pre><p>启动主从同步进程<br><code>start slave;</code><br>检查状态<br><code>show slave status \G</code><br><img src="https://pic.8oh.com.cn/cos/2022/03/09/9ce173abdfec8_1646817601.png" alt="186.png" title="186.png"><br>上面的两个进程都显示YES则表示配置成功</p><p>到此基本主从配置就完成了。<br>需要注意的是，一旦主库发生重启、当机等情况，需要检测数据一致性后才能start slave</p><h1>IPVS Keepalived配置关键服务</h1><p>部分服务是依赖其他服务进行改动的，所以当其他服务暂不可用的时候实际是不应影响这些服务的。<br>所以需要组件一个小型的虚拟网络实现ipvs，或者是采用hosts的方式进行主机指定，但是并不适用于那些只允许ip的应用</p><p>to be continue...</p><h1>参考</h1><p><a href="https://www.cnblogs.com/kylinlin/p/5258719.html">MySQL主从复制</a><br><a href="https://www.cnblogs.com/hllnj2008/p/5206449.html">mysqldump过滤数据库</a><br><a href="https://blog.csdn.net/chenxun1522/article/details/100717163">mysql主从配置忽略特定数据库</a><br><a href="https://blog.csdn.net/weixin_34109408/article/details/92607977">mysql binlog 忽略和记录指定库</a></p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/195/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/mysql/</wfw:commentRss>
</item>
<item>
<title>MySQL 用户权限管理</title>
<link>https://dwt.life/archives/148/</link>
<guid>https://dwt.life/archives/148/</guid>
<pubDate>Thu, 02 Dec 2021 05:43:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[删除权限REVOKE ALL PRIVILEGES ON `8oh`.* FROM &#039;8oh&#039;@&#039;%&#039;; GRANT USAGE ON `8oh`.* T...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>删除权限</p><pre><code class="lang-sql">REVOKE ALL PRIVILEGES ON `8oh`.* FROM &#039;8oh&#039;@&#039;%&#039;; GRANT USAGE ON `8oh`.* TO &#039;8oh&#039;@&#039;%&#039;;</code></pre><p>除了Grant权限赋予：</p><pre><code class="lang-sql">REVOKE ALL PRIVILEGES ON `8oh`.* FROM &#039;8oh&#039;@&#039;%&#039;; GRANT ALL PRIVILEGES ON `8oh`.* TO &#039;8oh&#039;@&#039;%&#039;;</code></pre><p>移除Grant权限</p><pre><code class="lang-sql">REVOKE ALL PRIVILEGES ON `8oh`.* FROM &#039;8oh&#039;@&#039;%&#039;; REVOKE GRANT OPTION ON `8oh`.* FROM &#039;8oh&#039;@&#039;%&#039;; GRANT ALL PRIVILEGES ON `8oh`.* TO &#039;8oh&#039;@&#039;%&#039;;</code></pre><p>赋予只读权限</p><pre><code class="lang-sql">GRANT SELECT, DELETE, SHOW VIEW ON `8oh`.* TO &#039;8oh&#039;@&#039;%&#039;;</code></pre><p>其实就是移除了所有权限然后再根据需求重新赋予权限</p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/148/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/mysql/</wfw:commentRss>
</item>
</channel>
</rss>