这篇文章主要围绕如何给php+mysql架构的网站换域名和php从网页修改数据库展开,旨在为您提供一份详细的参考资料。我们将全面介绍如何给php+mysql架构的网站换域名的优缺点,解答php从网页修
这篇文章主要围绕如何给php+mysql架构的网站换域名和php从网页修改数据库展开,旨在为您提供一份详细的参考资料。我们将全面介绍如何给php+mysql架构的网站换域名的优缺点,解答php从网页修改数据库的相关问题,同时也会为您带来apache+php+mysql组合开发的网站,放到iis+php+mysql会有什么有关问题么、cPanel主机面板让你轻松更换域名转移MYSQL数据库[组图]_MySQL、MySQL学习笔记之MySQL架构、MySQL性能优化(一):MySQL架构与核心问题的实用方法。
本文目录一览:- 如何给php+mysql架构的网站换域名(php从网页修改数据库)
- apache+php+mysql组合开发的网站,放到iis+php+mysql会有什么有关问题么
- cPanel主机面板让你轻松更换域名转移MYSQL数据库[组图]_MySQL
- MySQL学习笔记之MySQL架构
- MySQL性能优化(一):MySQL架构与核心问题
如何给php+mysql架构的网站换域名(php从网页修改数据库)
昨天帮客户给一个网站换域名,发现客户也做过很多的尝试,但没有成功。虽然很多程序能直接给网站换域名,但并不是所有的网站都可以。
就像这个客户一样,它的程序就不行。因为老的域名存在于三个地方:
1、数据库中
2、模板中
3、程序中
那么,只修改一个地方,就不行。需要三个地方全部都替换才可以。这里给你一个万能的步骤:
第一步:数据库导出,然后用vs code打开sql文件批量替换成新域名
如果你以前是A域名,现在需要改成B域名,就这样操作:
这要比直接用数据库软件或者去后台修改,要方便很多,快速很多。因为后台你需要挨个找,有的程序每篇文章都有老链接。
第二步:程序里批量查找换成A域名
方法与sql中替换域名是类似的。
第三步:用新的数据库sql文件,和新的修改过的程序,架构网站
这里不用详细说了,上传到服务器,然后处理一下,就OK了。这个时候网站里边的老链接就被彻底替换掉了。
这种办法是比较通用的,不管是什么程序,都可以这样操作。
百度竞价关键词出价技巧有哪些?
一、关键词出价策略百度竞价推广中,根据不同的产品、不同地域的消费水平,我们可以通过调整关键词出价的方式进行控制成本。1、对于竞争激烈的词我们可以将价格调低一些,比如原本是10元...
网站标题和关键词的关系是什么?
网站的标题就是用户搜索的词汇或者短语。在搜索引擎中,一个页面通常由两个部分组成:网页主体(即内容)与链接指向的部分。而这两个部分是相互的。那么如何让这两部分的权重都提升呢?这就...
seo短视频优化攻略
一、短视频优化攻略之标题:标题是吸引用户的关键因素,所以一定要重视起来。1、关键词的选取短视频内容中要包含有用户搜索词,并且这个关键词在标题中出现的频次要高。2、内容的布局围绕...
企业网站如何快速被搜索引擎收录
对SEO推广很多人并不陌生,很多站长遇到类似的问题,就是网站的排名没有,特别是一个刚刚接手的新站,网站排名都没有。因此,要怎样才可实现新站排名和收录增长?下面小编将与大家分享下...
企业网站制作需要做策划方案吗?
移动互联网的快速发展,手机网站在近几年也开始赶上潮流了。企业为跟上时代的步伐,也为自己建设手机网站,主要的目的是可以通过手机网站让更多人知道企业,提高企业的知名度。任何事情前都...
延伸阅读
apache+php+mysql组合开发的网站,放到iis+php+mysql会有什么有关问题么
apache+php+mysql组合开发的网站,放到iis+php+mysql会有什么问题么 ,这两个组合之间有什么区别??
------解决方案--------------------
理论上不会有什么问题。
------解决方案--------------------
php5.4之后,微软也对php进行的大规模的修复,令Windows的IIs也大性能的支持php,就连微软都来支持php你说IIs能不好吗/
------解决方案--------------------
不会有什么问题
------解决方案--------------------
一般不会有问题。但如果你的站需要高性能,还是nginx+php-fpm吧
cPanel主机面板让你轻松更换域名转移MYSQL数据库[组图]_MySQL
精博的域名已经由 essentialblog.cn 改为 jingpin.org,下面介绍我是如何更换域名的。
一、cPanel 上的操作:
在主机的 cPanel 上可以执行以下 4 个步骤:
第一步:添加附加域名
在 cPanel 控制面板上找到 “附加域” 这一项,然后添加你的新域名。
第二步:添加数据库
在 MySQL 数据库里面生成新的数据库。
第三步:复制文件
要把原来域名对应的 WordPress 所有文件复制到新域名的空间上,可以点击“文件管理器”,选择原来域名对应的 WordPress 所有文件和文件夹,点击“复制”,然后输入新域名所对应的文件夹路径,点击 “Copy File(s)”。
第四步:修改 wp-config.php 文件
通过 “文件管理器” 打开新域名所对应 WordPress 的 wp-config.php 文件,把旧的数据库改为新的数据库,如果新数据库的用户名和密码和旧数据库的不一样,也需要修改。
二、phpMyAdmin 的操作
这其实也是在 cPanel 上操作,为了强调,这里抽出来讲。
第五步:复制数据库
在 cPanel 上点击 phpMyAdmin (中文版 cPanel 翻译成 “phpMy 管理” ),然后选择原来域名的数据库,接着点击“操作”,在“复制数据库到:” 一栏输入新添加的数据库名称(全称,例如 young_jingpin),并取消 “CREATE DATABASE before copying” 前面的勾勾,然后点击“执行”。
第六步:修改数据库
在 phpMyAdmin 中选择新建的数据库,然后点击 “SQL”,并在输入以下代码:
UPDATE wp_options SET option_value = replace( option_value, ‘http://www.essentialblog.cn’, ‘http://jingpin.org’ ) WHERE option_name = ‘home’ OR option_name = ’siteurl’;
UPDATE wp_posts SET post_content = replace( post_content, ‘http://www.essentialblog.cn’, ‘http://jingpin.org’ ) ;
UPDATE wp_posts SET guid = replace( guid, ‘http://www.essentialblog.cn’, ‘http://jingpin.org’ ) ;
操作时注意把 www.essentialblog.cn 改为你的旧域名,把 jingpin.org 改为你的新域名。
这步完成了之后,你访问新的域名时,就会看到和原来域名一模一样的 WordPress 博客了。但是我弄完之后发现除了主页之外,其他页面都无法访问,后来在胡戈戈同学的指导下,多做了以下一个步骤:
第七步:保存固定链接
在 WordPress 管理后台把“设置”选项里面的“固定链接”打开之后,再点击一下“保存更改”就可以了。这步很无聊,但是却不能少。
以上 7 个步骤下来,其实就完成了一件事,那就是复制了一个一模一样的 WordPress 博客。在确保新博客一切链接正常之后,需要把旧域名重新定向到新域名的博客,使得别人访问你的旧域名时,就会转到你的新域名博客,其操作方法如下:
第八步:301 永久重定向
在原来域名的 .htaccess 文件上添加以下代码:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.essentialblog.cn
RewriteRule (.*) http://jingpin.org/$1 [R=301,L]
如果你之前没有 .htaccess 文件,可以把以上代码复制粘贴到记事本上,并以 “ .htaccess” 作为文件名保存,然后上传到原来域名所对应的 WordPress 文件夹根目录。
顺便说一下,原来 essentialblog.cn 对应的“ .htaccess” 文件上有以下代码:
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
如果不把这个代码删掉,那么 essentialblog.cn 可以正常跳转到 jingpin.org,但是 essentialblog.cn/about 却不能跳转到 jingpin.org/about,把代码删掉之后就可以了。截图上的 .htaccess 的文件还有以下代码:
RewriteCond %{HTTP_HOST} ^essentialblog.cn
RewriteRule (.*) http://www.essentialblog.cn/$1 [R=301,L]
这则代码是把 essentialblog.cn 定向到 www.essentialblog.cn 的,这样如果有人访问 essentialblog.cn/about,那么他们也会看到 jingpin.org/about 而不是 404 错误页面。
到这里,整个域名的更换算是完成了,以后你就可以直接在新域名对应的 WordPress 上写博客了。
MySQL学习笔记之MySQL架构
MySQL 最重要、最与众不同的特性是它的存储引擎架构,这种架构的设计将查询处理及其他系统任务和数据的存储/提取相分离。这种处理和存储分离的设计可以在使用时根据性能、特性,以及其他需求来选择数据存储的方式。
MySQL 的逻辑架构
MySQL 逻辑架构图
最上层的服务并不是MySQL 所独有的,大多数基于网络的客户端/服务器的工具或者服务都有类似的架构。比如连接处理、授权验证、安全等。
第二层架构是MySQL 比较有意思的部分。大多数MySQL的核心服务功能都在这一层,包括查询解析、分析、优化、缓存以及所有的内置函数(例如,日期、时间、数学和加密函数),所有跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。
第三层包含了存储引擎。存储引擎负责MySQL中数据的存储和提取。和GNU/Linux下的各种文件系统一样,每个存储引擎都有它的优势和劣势。服务器通过API于存储引擎进行通信。这些接口屏蔽了不同存储引擎之间的差异,使得这些差异对上层的查询过程透明。存储引擎API包含了几十个底层函数,用于执行诸如“开始一个事务”或者“根据主键提取一行记录”等操作。但存储引擎不会去解析SQL,不同存储引擎之间也不会相互通信,而只是简单地响应上层服务器的请求。
连接管理与安全性
每个客户端连接都会在服务器进行中拥有一个线程,这个连接的查询只会在这个单独的线程中执行,该线程只能轮流在某个CPU核心或者CPU中运行。服务器会负责缓存线程,因此不需要为每一个新建的连接创建或者销毁线程。
当客户端(应用)连接到MySQL 服务器时,服务器需要对其进行认证。认证基于用户名、原始主机信息和密码。如果使用了安全套接字(SSL)的方式连接,还可以使用X.509证书认证。一旦客户端连接成功,服务器会继续认证该客户端是否具有执行某个特定查询对方的权限(例如,是否允许客户端对world数据库的Country表执行SELECT语句)。
优化与执行
MySQL 会解析查询,并创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询、决定表的读写顺序,以及选择合适的索引等。用户可以通过特殊的关键字提示(hint)优化器,影响它的决策过程。也可以请求优化解释器(explain)优化过程的各个因素,使用户可以知道服务器是如何进行优化决策的,并提供一个参考基准,便于用户重构查询和schema、修改相关配置,使应用尽可能高效运行。
优化器并不关心表使用的是什么存储引擎,但存储引擎对优化查询是有影响的。优化器会请求存储引擎提供容量或某个操作的开销信息,以及表数据的统计信息等。例如,某些存储引擎的某种索引,可能对一些特定的查询有优化。
对于SELECT语句,在解析查询之前,服务器会线检查查询缓存(Query Cache),如果能够在其中找到对应的查询,服务器就不必再执行查询解析、优化和执行的整个过程,而是直接返回查询缓存中的结果集。
并发控制
无论何时,只要有多个查询需要在同一时刻修改数据,都会产生并发控制的问题。
以Unix 系统的email box为例,典型的mbox文件格式是非常简单的。一个mbox邮箱中所有的邮件都串行在一起,彼此首位相连。这种格式对于读取和分析邮件信息非常友好,同时投递邮件也很容易,只要在文件末尾加新的邮件内容即可。
但如果两个进程在同一时刻对同一个邮箱投递邮件,会发生什么情况?显然,邮箱的数据会被破坏,两封邮件的内容会交叉地附加在邮箱文件的莫问。设计良好的邮箱投递系统会通过锁(lock)来防止数据损坏。如果客户驶入投递邮件,而邮箱已经被其他客户锁住,那就必须等待,直到锁释放才能进行投递。
这种锁的方案在实际应用环境中虽然工作良好,但并不支持并发处理。因为在任意一个时刻,只有一个进程可以修改邮箱数据,这在大容量的邮箱系统中是个问题。
读写锁
从邮箱中读取数据没有这样的麻烦,即使同一时刻多个用户并发读取也不会有什么问题。因为读取不会修改数据,所以不会出错。但如果某个客户正在读取邮箱,同时另一个用户试图删除编号为25的邮件,会产生什么结果?结论是不确定,读的客户可能会报错退出,也可能读到不一致的邮箱数据。所以,为安全起见,即使读取邮箱也需要特别注意。
如果把上述的邮箱当成数据库中的一张表,把邮件当成表中的一行记录,就很容易看出,同样的问题依然存在。从很多方面来说,邮箱就是一张简单的数据库表。修改数据库表中的记录,和删除或者修改邮箱中的邮件信息,十分类似。
解决这类经典问题的方法就是并发控制,其实非常简单。在处理并发读或者写时,可以通过实现一个由两种类型的锁组成的锁系统来解决问题。这两种类型的锁通常被称为共享锁(shared lock)和排他锁(exclusive lock),也叫读锁(read lock)和写锁(write lock)。
锁的概念如下:读锁是共享的,或者说是相互不阻塞的。多个客户在同一时刻可以同时读取同一个资源,而互不干扰。写锁则是排他的,也就是说一个写锁会阻塞其他的写锁和读锁,这是处于安全策略的考虑,只有这样,才能确保在给定的时间里,只有一个用户能执行写入,并防止其他用户读取正在写入的同一资源。
在实际的数据库系统中,每时每刻都在发生锁定,当某个用户在修改某一部分数据时,MySQL 会通过锁定防止其他用户读取同一数据。大多数时候,MySQL 锁的内部管理都是透明的。
锁粒度
一种提高共享资源并发性的方式就是让锁定对象更有选择性。尽量只锁定需要修改的部分数据,而不是所有的资源。更理想的方式是,只对会修改的数据片进行精确的锁定。任何时候,在给定的资源上,锁定的数据量越少,则系统的并发程度越高,只要相互之间不发生冲突即可。
问题是加锁也需要消耗资源。锁的各种操作,包括获得锁、检查锁是否已经解除、释放锁等,都会增加系统的开销。如果系统话费大量的时间来管理锁,而不是存取数据,那么系统的性能可能会因此受到影响。
所谓的锁策略,就是在锁的开销和数据安全性之间寻求平衡,这种平衡当然也会影响到性能。
MySQL 数据库提供了多种选择。每种MySQL存储引擎都可以实现自己的锁策略和锁粒度。在存储引擎设计中,锁管理是个非常重要的决定。将锁粒度固定在某个级别,可以为某些特定的应用场景提供更好的性能,但同时会失去对另外一些应用场景的良好支持。
表锁(table lock)
表锁是 MySQL中最基本的锁策略,并且是开销最小的策略。表锁非常类似于前文中描述的邮箱加锁机制:它会锁定整张表。一个用户对表进行写操作(插入、删除、更新等)前,需要先获得写锁,这回阻塞其他用户对该表的所有读写操作。只有没有写锁时,其他读取的用户才能获得读锁,读锁之间是不互相阻塞的。
在特定的场景中,表锁也可能有良好的性能。例如,READ LOCK 表锁支持某些类型的并发写操作。另外,写锁也比读锁有更高的优先级,因此一个写锁的请求可能会被插入到读锁队列的前面(写锁可以插入到锁队列的前面,反之读锁则不能插入到写锁的前面)。
进过存储引擎可以管理自己的锁,MySQL 本身还是会使用各种有效的表锁来实现不同的目的。例如,服务器会为诸如ALTER TABLE之类的语句使用表锁,而忽略存储引擎的锁机制。
行级锁(row lock)
行级锁可以最大成都的支持并发处理(同时也带来了最大的开销)。众所周知,在InnoDB和XtraDB,以及其他一些存储引擎中实现了行级锁。行级锁只在存储引擎层实现,而MySQL服务器没有实现。服务器层完全不了解存储引擎中的锁实现。
事务
事务就是一组原子性的SQL查询,或者说是一个独立的工作单元。如果数据库存储引擎能够成功地对接数据库应用该组查询的全部语句,那么就执行该组查询。如果其中有任何一条语句因为崩溃或者其他原因无法执行,那么所有的语句都不会执行。也就是说,事务内的语句,要么全部执行成功,要么全部执行失败。
原子性(atomicity)
一是个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。
一致性(consistency)
数据库总是从一个一致性状态转换到另一个一致性的状态。
隔离性(isolation)
通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。
持久性(durability)
一旦事务提交,则其所做的修改就会永久保存到数据库中。
隔离级别
READ UNCOMMITTED(未提交读)
在READ UNCOMMITED级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为胀读(Dirty Read)。
READ COMMITED(提交读)
大多数数据库系统的默认隔离级别都是READ COMMITED(但MySQL不是)。READ COMMITED满足前面提到的隔离性的简单定义:一个事务开始时,只能“看见”已经提交的事务所做的修改。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候也叫做不可重复读,因为两次执行同样的查询,可能会得到不一样的结果。
REPEATABLE READ(可重复读)
REPEATABLE READ 解决了脏读的问题。该级别保证了在同一个事务中多次读取同样记录的结果是一致的。但是理论上,可重复读隔离级别还是无法解决另一个幻读的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围内的记录时,会产生幻行。InnoDB和XtraDB 存储引擎通过过版本并发控制(MVCC)解决了幻读的问题。
SERIALIZABLE(可串行化)
SERIALIZABLE 是最高的隔离级别。它通过强制事务串行化执行,避免了幻读问题。简单来说,SERIALIZABLE 会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别。
ANSI SQL 隔离级别
死锁
死锁是指两个或者多个事务在同一资源上互相占用,并请求锁定对方占用的资源,从而导致而行循环的现象。当多个事务试图以不同顺序锁定资源时,就可能会产生死锁。多个事务同时锁定同一个资源时,也会产生死锁。
多版本并发控制
MySQL 的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,它们一般都同时实现了多版本并发控制(MVCC)。不仅是MySQL,包括Oracle、PostgreSQL 等其他数据库系统也都实现了MVCC,但各自的实现机制不尽相同,因为MVCC没有一个统一的实现标准。
可以认为MVCC是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低。虽然实现机制有所不同,但大都实现了非阻塞的读操作,写操作也只锁定必要的行。
MVCC的实现,是通过保存数据在某一个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事务看到的数据都是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。
不同存储引擎的MVCC的实现是不同的,典型的有乐观并发控制和悲观并发控制。
InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存了行的过期时间(或删除时间)。当然存储的并不是实际的时间值,而是系统版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。下面是在REPPEATABLE READ隔离级别下,MVCC具体是如何操作的。
SELECT
InnoDB 会根据以下两个条件去检查每行记录:
- InnoDB只查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。
- 行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。
INSERT
InnoDB 为新插入的每一行保存当前系统版本号作为行版本号。
DELETE
InnoDB 为删除的每一行保存当前系统版本号作为删除标识。
UPDATE
InnoDB 为插入一行新纪录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为删除标识。
保存这两个额外系统版本号,使大多数读操作都可以不通加锁。这样设计使得读操作很简单,性能很好,并且也能保证只会读取到符合标准的行。不足之处是每行记录都需要额外的存储空间,需要做很多的行检查工作,以及一些额外的维护工作。
MVCC只在REPEATABLE READ和READ COMMITED两个隔离级别下工作。其他两个隔离级别都和MVCC不兼容,因为READ UNCOMMITED总是读取最新的数据行,而不是符合当前事务版本的数据行。而SERIALIZABLE则会对所有读取的行都加锁。
总结
MySQL 拥有分层的架构。上层是服务器层的服务和查询执行引擎,下层则是存储引擎。虽然有很多不同作用的插件API,但存储引擎API还是最重要的。如果能理解MySQL 在存储引擎和服务层之间处理查询时如何通过API来回交互,就能抓住MySQL 的核心基础架构的精髓。
书读百遍,其义自现。
有时候不得不承认自己的无知。从大二就开始接触MySQL,但是一直都在尝试着去用。随着时间的流逝,如今用MySQL 对我来说问题已经不大了,到了学习MySQL是如何实现的阶段了。
这里面的InnoDB的MVCC给我十分深刻的印象,因为我最近做的一个供应商信息版本控制,实现的设计和这里大致相同,这种思想上的共通,给人以启迪。
本文作者: 荒古
本文链接: https://haxianhe.com/2019/08/...
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!
欢迎关注我的公众号:荒古传说
MySQL性能优化(一):MySQL架构与核心问题
一、前言
作为程序员的你,数据库作为一门必修课,而MySQL数据库毫无疑问已经是最常用的数据库了。系统的稳定、高效、高并发等指标,很大程度上取决于数据库性能是否够优,可见性能优化的重要性,这也就不难理解各位在任何一场面试中都会被问及到数据库调优相关的问题。
因此,这就是我为何考虑写该系列文章的主要原因,希望该系列文章(MySQL性能优化)能够给你带来收获,让你更系统、更全面的掌握MySQL性能优化的技能、技巧。该系列文章将会持续分享、更新,如果觉得现在或者将来可能对你有用,不妨持续关注、收藏。
在MySQL性能优化之前,你有必要重新再认识下MySQL,便于后续更容易理解MySQL性能优化中涉及到的知识点。本文将从MySQL架构、核心问题来针对性展开讨论,这也将是MySQL性能优化系列文章的开篇之作。
二、MySQL逻辑架构
想深入探究MySQL之前,有必要了解一下MySQL的逻辑架构,逻辑架构图如下:
MySQL的逻辑架构中,分为三层,如上图红色虚线框的三部分。
最上层架构并不是MySQL所独有的,大多数基于客户端/服务器形态的系统或者服务,都有类似的架构,其中包含MySQL的连接处理、授权认证、安全控制等等。
第二层架构是MySQL中最为核心的部分,其中包括查询解析、分析、优化、缓存以及所有的内置函数(如:日期、时间、函数等),所有跨存储引擎的功能都在这一层实现,例如:存储过程、触发器、视图等。
语言 | 方法 |
---|---|
7860 | v6KpAB5syX |
hj7aV | 抖音小程序 |
8905 | 2008/03/23 20:40:11 |
第三层架构是存储引擎。存储引擎负责MySQL中数据的存储和提取,类似与Linux系统下的各种文件系统一样,不同存储引擎都有各自的优势和劣势,不同场景可选择不同的引擎。不同存储引擎之间是不会相互通信的,只是简单地响应上层的请求。
三、如何控制高并发的读写?
无论何时,对于数据库而言,高并发的读写操作是很常见的,针对同一条记录在同一时刻进行修改、查询操作,都会产生并发控制的问题,处理不当将会出现大量的脏数据。那么,如何控制高并发的读写操作呢?
1.读写锁
在我们学习任何一门语言时,针对处理并发问题都会选择锁机制来解决并加以控制,这也是解决并发控制的经典方法,MySQL也不例外。在MySQL处理高并发的读或者写时,可以通过实现两种类型的锁来解决,这两种类型的锁通常被称为共享锁(Shared lock)和排他锁(exclusive lock),其实就是大家叫的读锁(read lock)和写锁(write lock)。
读锁,是共享的,也就是说是互相不阻塞的。多个请求在同一时刻可以同时读取同一条记录,而互不干扰。
写锁,是排他的,也就是说一个写锁会阻塞其他的写锁和读锁,避免在写的过程中进行读、再写的操作,这更是出于安全的考虑,只有这样才能确保数据的准确、干净。在数据库中,每时每刻都在发生锁定,当某次请求修改数据时,MySQL都会通过锁来防止其他请求读取同一数据。
2.锁策略
有了锁的机制,就能更好的控制高并发的读写操作,我们都知道锁也是有范围的,锁定对象范围的选择,更具有挑战性。尽量只锁定需要修改的部分数据,而不是所有数据,这也是选择锁定对象范围最想满足的。锁定范围越精确,锁定的数据量就越小,则系统的并发程度越高,加锁本身消耗的资源也就越小。
上述提到的无非就是设定锁的粒度,而MySQL则提供了多种选择,每种MySQL存储引擎都可以实现自己的锁策略和锁粒度。下面将介绍两种最常用的锁策略。
2.1 表级锁(table lock)
表级锁是MySQL最基本的锁策略,并且是开销最小的策略,它会锁定整张表。一个请求在对表进行写操作(插入、修改、删除等)前,需要先获得写锁,此时会阻塞其他请求对该表的所有读写操作。只有没有写锁时,其他请求才能读取并获得读锁,读锁之间是不相互阻塞的。
尽管存储引擎可以管理自己的锁,而且MySQL本身还会使用各种有效的表级锁来实现不同的目的。例如,诸如ALTER TABLE
之类的语句就使用了表级锁,而忽略存储引擎的锁机制。
开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。
表级锁,更适用于以查询为主,只有少量按索引条件更新数据的应用。
2.2 行级锁(row lock)
行级锁可以最大程度地支持并发处理(同时也带来了最大的锁开销)。
开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度最高。
行级锁,更适合于有大量按索引发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理系统。
四、MySQL存储引擎是怎样的?
在文件系统中,MySQL将每个数据库(即:schema
)保存为数据目录data下的一个子目录。创建表时,MySQL会在数据库data目录下创建一个和表同名的.frm
文件来保存表的定义。
不同的存储引擎保存数据和索引的方式是不同的,但表的定义则是在MySQL服务层统一处理的。
可以使用show table status like ''表名'' \G
命令来查看表的存储引擎以及表的其他相关信息,例如,查看mysql数据库中的user表:
mysql> use mysql;
No connection. Trying to reconnect...
Connection id: 20587
Current database: *** NONE ***
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show table status like ''user'' \G;
*************************** 1. row ***************************
Name: user
Engine: MyISAM
Version: 10
Row_format: Dynamic
Rows: 3
Avg_row_length: 125
Data_length: 512
Max_data_length: 281474976710655
Index_length: 4096
Data_free: 136
Auto_increment: NULL
Create_time: 2019-07-12 14:45:17
Update_time: 2019-12-20 15:55:44
Check_time: NULL
Collation: utf8_bin
Checksum: NULL
Create_options:
Comment: Users and global privileges
1 row in set (0.00 sec)
ERROR:
No query specified
从查询结果的Engine
字段可以表明,user表的存储引擎类型为MyISAM
,其他字段在此就不一一说明,如想详细了解可查阅相关文档。
在了解MySQL存储引擎前,可以先看看你的MySQL数据库支持哪些存储引擎,可通过show engines
命令查看。我使用的MySQL版本为5.7.25
,查看结果如下图所示:
从上述结果可以看出,支持的存储引擎有: InnoDB
、Mrg_Myisam
、Memory
、Blackhole
、MyISAM
、CSV
、 Archive
、Performance_Schema
、Federated
,其中也做了简单的解释说明。
本文只针对InnoDB
、MyISAM
两种最常见的存储引擎进行着重说明,其它存储引擎只做简单说明,详细可查阅官方文档。
1.InnoDB存储引擎
InnoDB
是MySQL的默认事务型引擎,也是最重要、使用最广泛的存储引擎,并且有行级锁定和外键约束。
它被设计用来处理大量的短期(short-lived)事务,短期事务大部分情况是正常提交,很少会被回滚。InnoDB的性能和自动崩溃恢复特性,使得它在非事务型存储的需求中也很流行。除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB
引擎。
InnoDB
的适用场景/特性,有以下几种:
- 经常更新的表,适合处理多重并发的更新请求。
- 支持事务。
- 可以从灾难中恢复(通过bin-log日志等)。
- 外键约束。只有他支持外键。
- 支持自动增加列属性auto_increment。
2.MyISAM存储引擎
MyISAM
提供了大量的特性,包括全文检索、压缩等,但不支持事务和行级锁,支持表级锁。
对于只读的数据,或者表较小、可以忍受修复操作的场景,依然可以使用MyISAM。
MyISAM
的适用场景/特性,有以下几种:
- 不支持事务的设计,但是并不代表着有事务操作的项目不能用
MyISAM
存储引擎,完全可以在程序层进行根据自己的业务需求进行相应的控制。 - 不支持外键的表设计。
- 查询速度很快,如果数据库
insert
和update
的操作比较多的话比较适用。 - 整天 对表进行加锁的场景。
MyISAM
极度强调快速读取操作。MyIASM
中存储了表的行数,于是SELECT COUNT(*) FROM TABLE
时只需要直接读取已经保存好的值而不需要进行全表扫描。如果表的读操作远远多于写操作且不需要数据库事务的支持,那么MyIASM
也是很好的选择。
3.MySQL内建的其他存储引擎
MySQL还有一些特殊用途的存储引擎,在一些特殊场景下用起来会很爽的。在MySQL新版本中,有些可能因为一些原因已经不再支持了,还有一些会继续支持,但是需要明确地启用后才能使用。
3.1 Archive存储引擎
Archive
引擎只支持insert
和select
操作,并且在MySQL 5.1之前连索引都不支持。
Archive
引擎会缓存所有的写并利用zlib对插入的行进行压缩,所以比MyISAM
引擎的磁盘I/O更少。但是每次select
查询都需要进行全表扫描,所以Archive更适合日志和数据采集类应用,况且这类应用在做数据分析时往往需要全表扫描。
Archive
引擎支持行级锁和专用的缓冲区,所以可以实现高并发的插入。在一个查询开始直到返回表中存在的所有行之前,Archive
引擎会阻止其他的select
执行,以实现一致性读。另外,这也实现了批量插入在完成之前对读操作是不看见的。
3.2 Blackhole存储引擎
Blackhole
引擎没有实现任何的存储机制,它会丢失所有插入的数据,不做任何保存。怪哉,岂不是一无用处?
但是服务器会记录Blackhole
的日志,所以可以用于复制数据到备库,或者只是简单地记录到日志。这种特殊的存储引擎可以在一些特殊的复制架构和日志审核时发挥作用。
但这种存储引擎的存在,至今还是有些难以理解。
3.3 CSV存储引擎
CSV
引擎可以将普通的CSV
文件作为MySQL的表来处理,但这种表不支持索引。
CSV
引擎可以在数据库运行时拷入或者拷出文件,可以将Excel等电子表格软件中的数据存储为CSV
文件,然后复制到MySQL数据目录下,就能在MySQL中打开使用。同样,如果将数据写入到一个CSV
引擎表中,其他的外部程序也能立即从表的数据文件中读取CSV
格式的数据。
因此,CSV
引擎可以作为一种数据交换的机制,是非常有用的。
3.4 Memory存储引擎
如果需要快速地访问数据,并且这些数据不会被修改,重启以后丢失也没有关系,那么使用Memory
引擎是非常有用的。Memory
引擎至少比MyISAM
引擎要快一个数量级,因为所有的数据都保存在内存中,不需要进行磁盘I/O。Memory
引擎的表结构在重启以后还会保留,但数据会丢失。
Memory
引擎在很多场景下可以发挥很好的作用:
- 用于查找或者映射表,例如将邮箱和州名映射的表。
- 用于缓存周期性聚合数据的结果。
- 用于保存数据分析中产生的中间数据。
Memory
引擎支持Hash索引,因此查找非常快。虽然Memory
的速度非常快,但还是无法取代传统的基于磁盘的表。Memory
引擎是表级锁,因此并发吸入的性能较低。
如果MySQL在执行查询的过程中,需要使用临时表来保存中间结果,内部使用的临时表就是Memory引擎。如果中间结果太大超出了Memory
的限制,或者含有BLOB
或TEXT
字段,则临时表会转换成MyISAM
的引擎。
看了上面的说明,大家就会经常混淆Memory和临时表了。临时表是指使用
CREATE TEMPORARY TABLE
语句创建的表,它可以使用任何存储引擎,因此和Memory不是一回事。临时表只在单个连接中可见,当连接断开时,临时表也将不复存在。
关于临时表和Memory引擎的那些事
MySQL的存储引擎及第三方存储引擎,还有很多,在此就不一一介绍了,后续如有需要,再进一步来谈谈。
4.如何选择合适的存储引擎呢
这么多存储引擎,真是眼花缭乱,我们该如何选择呢?
大部分情况下,都会选择默认的存储引擎——InnoDB
,并且这也是最正确的选择,所以Oracle在MySQL 5.5版本时终于将InnoDB
作为默认的存储引擎了。
对于如何选择合适的存储引擎,可以简单地归纳为一句话:”除非需要用到某些InnoDB不具备的特性,并且没有其他可以替代,否则都应该优先选择InnoDB引擎”。
例如,如果要用到全文检索,建议优先考虑InnoDB
加上Sphinx
的组合,而不是使用支持全文检索的MyISAM
。当然,如果不需要用到InnoDB
的特性,同时其他引擎的特性能够更好地满足需求,就可以考虑一下其他存储引擎。
除非万不得已,建议不要混合使用多种存储引擎,否则可能带来一系列复杂的问题,以及一些潜在的bug和边界问题。
如果需要使用不同的存储引擎,建议考虑从以下几个因素进行衡量考虑。
今天关于如何给php+mysql架构的网站换域名和php从网页修改数据库的分享就到这里,希望大家有所收获,若想了解更多关于apache+php+mysql组合开发的网站,放到iis+php+mysql会有什么有关问题么、cPanel主机面板让你轻松更换域名转移MYSQL数据库[组图]_MySQL、MySQL学习笔记之MySQL架构、MySQL性能优化(一):MySQL架构与核心问题等相关知识,可以在本站进行查询。
本文标签: