数据库管理

Items filtered by date: 4月 2021

在Apache, PHP, MySQL的体系架构中,MySQL对于性能的影响最大,也是关键的核心部分。对于Discuz!论坛程序也是如此,MySQL的设置是否合理优化,直接影响到论坛的速度和承载量!同时,MySQL也是优化难度最大的一个部分,不但需要理解一些MySQL专业知识,同时还需要长时间的观察统计并且根据经验进行判断,然后设置合理的参数。 下面我们了解一下MySQL优化的一些基础,MySQL的优化我分为两个部分,一是服务器物理硬件的优化,二是MySQL自身(my.cnf)的优化。

 

一、服务器硬件对MySQL性能的影响①磁盘寻道能力(磁盘I/O),以目前高转速SCSI硬盘(7200转/秒)为例,这种硬盘理论上每秒寻道7200次,这是物理特性决定的,没有办法改变。MySQL每秒钟都在进行大量、复杂的查询操作,对磁盘的读写量可想而知。所以,通常认为磁盘I/O是制约MySQL性能的最大因素之一,对于日均访问量在100万PV以上的Discuz!论坛,由于磁盘I/O的制约,MySQL的性能会非常低下!解决这一制约因素可以考虑以下几种解决方案: 使用RAID-0+1磁盘阵列,注意不要尝试使用RAID-5,MySQL在RAID-5磁盘阵列上的效率不会像你期待的那样快。

②CPU 对于MySQL应用,推荐使用S.M.P.架构的多路对称CPU,例如:可以使用两颗Intel Xeon 3.6GHz的CPU,现在我较推荐用4U的服务器来专门做数据库服务器,不仅仅是针对于mysql。

③物理内存对于一台使用MySQL的Database Server来说,服务器内存建议不要小于2GB,推荐使用4GB以上的物理内存,不过内存对于现在的服务器而言可以说是一个可以忽略的问题,工作中遇到了高端服务器基本上内存都超过了16G。

 

二、MySQL自身因素当解决了上述服务器硬件制约因素后,让我们看看MySQL自身的优化是如何操作的。对MySQL自身的优化主要是对其配置文件my.cnf中的各项参数进行优化调整。下面我们介绍一些对性能影响较大的参数。 由于my.cnf文件的优化设置是与服务器硬件配置息息相关的,因而我们指定一个假想的服务器硬件环境:CPU: 2颗Intel Xeon 2.4GHz 内存: 4GB DDR 硬盘: SCSI 73GB(很常见的2U服务器)。

下面,我们根据以上硬件配置结合一份已经优化好的my.cnf进行说明:

#vim /etc/my.cnf以下只列出my.cnf文件中[mysqld]段落中的内容,其他段落内容对MySQL运行性能影响甚微,因而姑且忽略。


[mysqld]

 

port = 3306

 

serverid = 1

 

socket = /tmp/mysql.sock

 

skip-locking

 

#避免MySQL的外部锁定,减少出错几率增强稳定性。

 

skip-name-resolve

 

#禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求!

 

back_log = 384

 

#back_log参数的值指出在MySQL暂时停止响应新请求之前的短时间内多少个请求可以被存在堆栈中。 如果系统在一个短时间内有很多连接,则需要增大该参数的值,该参数值指定到来的TCP/IP连接的侦听队列的大小。不同的操作系统在这个队列大小上有它自己的限制。 试图设定back_log高于你的操作系统的限制将是无效的。默认值为50。对于Linux系统推荐设置为小于512的整数。

 

key_buffer_size = 256M

 

#key_buffer_size指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能。对于内存在4GB左右的服务器该参数可设置为256M或384M。注意:该参数值设置的过大反而会是服务器整体效率降低!

 

max_allowed_packet = 4M

 

thread_stack = 256K

 

table_cache = 128K

 

sort_buffer_size = 6M

 

#查询排序时所能使用的缓冲区大小。注意:该参数对应的分配内存是每连接独占,如果有100个连接,那么实际分配的总共排序缓冲区大小为100 × 6 = 600MB。所以,对于内存在4GB左右的服务器推荐设置为6-8M。

 

read_buffer_size = 4M

 

#读查询操作所能使用的缓冲区大小。和sort_buffer_size一样,该参数对应的分配内存也是每连接独享。

 

join_buffer_size = 8M

 

#联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每连接独享。

 

myisam_sort_buffer_size = 64M

 

table_cache = 512

 

thread_cache_size = 64

 

query_cache_size = 64M

 

#指定MySQL查询缓冲区的大小。可以通过在MySQL控制台观察,如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况;如果Qcache_hits的值非常大,则表明查询缓冲使用非常频繁,如果该值较小反而会影响效率,那么可以考虑不用查询缓冲;Qcache_free_blocks,如果该值非常大,则表明缓冲区中碎片很多。

 

tmp_table_size = 256M

 

max_connections = 768

 

#指定MySQL允许的最大连接进程数。如果在访问论坛时经常出现Too Many Connections的错误提 示,则需要增大该参数值。

 

max_connect_errors = 10000000

 

wait_timeout = 10

 

#指定一个请求的最大连接时间,对于4GB左右内存的服务器可以设置为5-10。

 

thread_concurrency = 8

 

#该参数取值为服务器逻辑CPU数量*2,在本例中,服务器有2颗物理CPU,而每颗物理CPU又支持H.T超线程,所以实际取值为4*2=8

 

skip-networking

 

#开启该选项可以彻底关闭MySQL的TCP/IP连接方式,如果WEB服务器是以远程连接的方式访问MySQL数据库服务器则不要开启该选项!否则将无法正常连接!

 

table_cache=1024

 

#物理内存越大,设置就越大.默认为2402,调到512-1024最佳

 

innodb_additional_mem_pool_size=4M

 

#默认为2M

 

innodb_flush_log_at_trx_commit=1

 

#设置为0就是等到innodb_log_buffer_size列队满后再统一储存,默认为1

 

innodb_log_buffer_size=2M

 

#默认为1M

 

innodb_thread_concurrency=8

 

#你的服务器CPU有几个就设置为几,建议用默认一般为8

 

key_buffer_size=256M

 

#默认为218,调到128最佳

 

tmp_table_size=64M

 

#默认为16M,调到64-256最挂

 

read_buffer_size=4M

 

#默认为64K

 

read_rnd_buffer_size=16M

 

#默认为256K

 

sort_buffer_size=32M

 

#默认为256K

 

thread_cache_size=120

 

#默认为60

 

query_cache_size=32M

 

※值得注意的是:很多情况需要具体情况具体分析

 

一、如果Key_reads太大,则应该把my.cnf中Key_buffer_size变大,保持Key_reads/Key_read_requests至少1/100以上,越小越好。

 

二、如果Qcache_lowmem_prunes很大,就要增加Query_cache_size的值。

 

下面是其它网友的补充:推荐参考

 

优化mysql数据库性能的十个参数(转)

 

(1)、max_connections:

 

允许的同时客户的数量。增加该值增加 mysqld 要求的文件描述符的数量。这个数字应该增加,否则,你将经常看到 too many connections 错误。 默认数值是100,我把它改为1024 。

 

(2)、record_buffer:

 

每个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。如果你做很多顺序扫描,你可能想要增加该值。默认数值是131072(128k),我把它改为16773120 (16m)

 

(3)、key_buffer_size:

 

索引块是缓冲的并且被所有的线程共享。key_buffer_size是用于索引块的缓冲区大小,增加它可得到更好处理的索引(对所有读和多重写),到你能负担得起那样多。如果你使它太大,系统将开始换页并且真的变慢了。默认数值是8388600(8m),我的mysql主机有2gb内存,所以我把它改为 402649088(400mb)。

 

4)、back_log:

 

要求 mysql 能有的连接数量。当主要mysql线程在一个很短时间内得到非常多的连接请求,这就起作用,然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。

 

back_log 值指出在mysql暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。只有如果期望在一个短时间内有很多连接,你需要增加它,换句话说,这值对到来的tcp/ip连接的侦听队列的大小。你的操作系统在这个队列大小上有它自己的限制。试图设定back_log高于你的操作系统的限制将是无效的。

 

当你观察你的主机进程列表,发现大量 264084 | unauthenticated user | xxx.xxx.xxx.xxx | null | connect | null | login | null 的待连接进程时,就要加大 back_log 的值了。默认数值是50,我把它改为500。

 

(5)、interactive_timeout:

 

服务器在关闭它前在一个交互连接上等待行动的秒数。一个交互的客户被定义为对 mysql_real_connect()使用 client_interactive 选项的客户。 默认数值是28800,我把它改为7200。

 

(6)、sort_buffer:

 

每个需要进行排序的线程分配该大小的一个缓冲区。增加这值加速order by或group by操作。默认数值是2097144(2m),我把它改为 16777208 (16m)。

 

(7)、table_cache:

 

为所有线程打开表的数量。增加该值能增加mysqld要求的文件描述符的数量。mysql对每个唯一打开的表需要2个文件描述符。默认数值是64,我把它改为512。

 

(8)、thread_cache_size:

 

可以复用的保存在中的线程的数量。如果有,新的线程从缓存中取得,当断开连接的时候如果有空间,客户的线置在缓存中。如果有很多新的线程,为了提高性能可以这个变量值。通过比较 connections 和 threads_created 状态的变量,可以看到这个变量的作用。我把它设置为 80。

 

(9)mysql的搜索功能

 

用mysql进行搜索,目的是能不分大小写,又能用中文进行搜索

 

只需起动mysqld时指定 --default-character-set=gb2312

 

(10)、wait_timeout:

 

服务器在关闭它之前在一个连接上等待行动的秒数。 默认数值是28800,我把它改为7200。

 

2G内存,针对站多,抗压型的设置,最佳:

 

table_cache=1024 物理内存越大,设置就越大.默认为2402,调到512-1024最佳

 

innodb_additional_mem_pool_size=4M 默认为2M

 

innodb_flush_log_at_trx_commit=1

 

(设置为0就是等到innodb_log_buffer_size列队满后再统一储存,默认为1)

 

innodb_log_buffer_size=2M 默认为1M

 

innodb_thread_concurrency=8 你的服务器CPU有几个就设置为几,建议用默认一般为8

 

key_buffer_size=256M 默认为218 调到128最佳

 

tmp_table_size=64M 默认为16M 调到64-256最挂

 

read_buffer_size=4M 默认为64K

 

read_rnd_buffer_size=16M 默认为256K

 

sort_buffer_size=32M 默认为256K

 

max_connections=1024 默认为1210

 

thread_cache_size=120 默认为60

 

query_cache_size=64M

 

一般:

 

table_cache=512

 

innodb_additional_mem_pool_size=8M

 

innodb_flush_log_at_trx_commit=0

 

innodb_log_buffer_size=4M

 

innodb_thread_concurrency=8

 

key_buffer_size=128M

 

tmp_table_size=128M

 

read_buffer_size=4M

 

read_rnd_buffer_size=16M

 

sort_buffer_size=32M

 

max_connections=1024

————————————————

版权声明:本文为CSDN博主「zhang MR」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_36202603/article/details/113321658

Published in 网络

用DISCUZ建立了一个论坛,打开发现速度非常慢很卡。查看network发现Waiting(TTFB)加载要5s多,另一个要10s,除了正常DISCUZ优化之外,以下也是解决方案之一:

解决方法:
1、网站根目录——config——打开 config_global 和 config_ucenter
define('UC_DBHOST', localhost'); 
修改为
define('UC_DBHOST', '127.0.0.1'); 
define('UC_DBHOST', '您服务器的ip地址');
2、网站根目录——uc_server——data——config.inc
define('UC_DBHOST', localhost'); 
修改为
define('UC_DBHOST', '127.0.0.1'); 
define('UC_DBHOST', '您服务器的ip地址');
注意:DX3.2 3.4 3.5里面略有不同,但是localhost这个是确定的,盘它就行。
 
 
 
Published in 网络

常用的论坛设计方法,总结如下:

一 分割思想:

1 数据库切分:用户库、主题库、回复库

2 数据表水平切分:用户库1-n、主题库1-n、回复库1-n (比如按时间分)

3 分布式数据库:每台计算机中都有DBMS的一份完整拷贝副本,并具有自己局部的数据库,位于不同地点的许多计算机通过网络互相连接,共同组成一个完整的、全局的大型数据库。

4 论坛功能可以进行分隔,不同的服务器负责不同的功能

5 用主从数据库,master是写, slave是读

6 把内容与其它信息分开,好处就是可以让每个表的文件最小化,对数据库操作压力会减小,这样保证每张表数据量很小,操作速度会快,也可以在这里使用缓存

二 索引:
针对是否建立索引有着一定的分歧: 我觉得建立索引还是很有必要的。理由如下:

1)建立索引可以加快检索速度,对于论坛读和写的比例相差很大,用户体验当然是读多写少,所以综合考虑还是要用索引,而且是加在常用的读关键字上。

2)索引之所以会降低更新的速度,是因为更新还包括对索引的更新,从更新帖子10万左右,这句话是说,我们可能对发帖标题,发帖内容,回复标题,回复内容这4个字段做更新。需要注意的是,这四个字段并不是用来建立表连接的字段,为了优化查询速度我们不会在这四个字段上建立索引,所以从这道题目出发,我们建立的索引不会影响更新帖子的性能。只要被索引的列(例如回复表的标题ID)不被频繁更新,即使索引所在地行的其它列被频繁update,索引也不会被更新从而产生性能消耗,一张表一天30万次的索引更新,因它引起的性能消耗小到即使数据库安装在奔腾3单核CPU下都能轻松承担下来。

3)对于更新的速度慢的问题,我们有解决的方法,你提交更新了后,前台可以让程序返回一个正确结果,后台开个线程异步慢慢跟新数据库就是了,反正更新成功的前提就是假设数据库连接永远正确并处于可靠状态。在数据库和用户之间建立一个缓冲区。(如,将更新的数据放到内存中,达到一定数量的时候再统一更新数据库。假如以100条为例,一旦内存中达到100条数据量将这100条数据统一入库。减少insert操作)

三 缓冲:
读的时候的缓冲:缓存路由表 主题缓存表(这个取每个区的前面100条记录),一般来说负载最大的就是主题的第一页,所以缓存表是个小表。 另外使用hibernate,在数据库上面加了一层缓存。 生成静态页,缓存最热,最新的帖子。 对于经常更新的数据都设计成单独表 ,这样可以最大程度的利用hibernate缓存 缓存常用的数据和表,利用缓存来将经常被访问的帖子留在内存中,为每条缓存的记录添加一个访问时间,如果长时间没被访问就从缓存中删除掉, 避免内存过大,每次用户看帖的时候,首先检索缓存中时候有需要的帖子,没有的话再访问数据库,然后将数据库返回的帖子信息存储到缓存中。 写的时候的缓冲:数据库和用户之间建立缓存,将更新的数据放在内存中,异步操作的。所有的写贴操作 放到一个队列然后批量执行插入数据库操作。 预估计的缓冲:假如用户第一次打开某标题,那将此标题的相关的前100条数据缓存到客户断。这样避开对数据库的直接查询,减少数据库压力。

四 代码优化
1尽量避免表的连接约束通过代码来实现约束 例如用户id的验证在用户登录时验证这样就可以把帖子表的用户id外键去掉这样就成了单表操作、查询 而连接可以通过触发来实现这样最多是查询了3个表而不是连接中的笛卡尔笛卡尔积 回复表的查询限定每次查询的记录数例如限定10条其它的通过点击触发来操作"注代码优化容易出现bug 原因有些开发工具本身有优化"

五 数据库性能调优
尽量用硬件来代替软件优化 原则就是能用硬件的尽量用硬件 比如磁盘阵列 RAID0 有条件用RAID10 加大内存 .避免小表上建索引 对论坛来说数据帖子和回复不是很重要 可以定期删除一些垃圾帖子 楼主说的几百万条记录的论坛对现在的数据库管理系统和计算机来说永不着刻意的优化,定期维护打包备份数据库就可以了 提高速度的关键:
1.建立合理的索引并在查询时充分利用;
2.避免使用关联,这样避免整表扫描;使用关联不如多次使用主键查询来的快;
3.一些处理的功能尽可能放到内存中来做,比如组织主题和回复;
4.海量缓存(使用静态页面也是个不错的做法)
5 定期对表进行转储

Published in 网络

Discuz论坛的会员保存在ucenter里面,跟DZ论坛是分开的。很多人搬家时忘了备份UCENTER数据。只备份了DZ论坛。结果搬家后发现会员登陆不上,会员数据丢失,如果旧的数据库没删除还好。如果空间被删。那基本找不回了。

然后还有一种情况,就是弃用无用的会员数据。只保留活跃会员 也可操作。

 

【特别针对:针对备份论坛但是没有备份ucenter导致会员丢失】

放弃所有会员的密码。直接只导入DZ论坛的 用户名 跟邮箱 到 UCENTER里面。然后发站内通知 公告:提醒会员根本注册时的邮箱找回密码。  甚至有条件可以群发邮件给会员。

 

密码(password)这一项是没有办法添加的,第一我不知道用户的密码是什么,第二UC会将密码MD5加密。所以密码索性就设置为空,即不导入密码。

所以需要导入的只需UID、用户名(username)、邮箱(email)三项就可以了(其他信息可以让会员将来重置)

但是考虑手动添加的话工作量太大

所以一直寻求可以批量添加的方法

结果查了一些资料,结合自身数据库情况,写了如下语句:

 

INSERT INTO`mysqlsjk1`.`uc_members` (

`uid` ,

`username` ,

`email`

)

SELECT `uid`,`username`,`email` FROM `wenliren`.`pre_common_member` WHERE uid>1 AND uid<60000

 

其中:

`mysqlsjk1`为数据库名;

`uc_members`为ucenter用户数据表;`uid` ,`username` ,`email` 为对应的三项表头;

`pre_common_member`为论坛会员数据表;

最后WHERE 1 到 60000 的范围可以自己选定,如果发生问题的时候已经控制不再有新注册用户的话,可以不设定上限。

 

进入网站的PHPmyadmin后台,进入Mysql管理,使用“SQL查询”,贴上以上代码(记得要替换自己的信息),执行。

这样,就完成了论坛数据表到ucenter数据的导入了。

PS:如果有人尝试的话,请做好数据表备份!

后续工作:选取这些会员,发送站点通知。通知选用Email发送,内容当然是提醒会员重置密码。

 

 

 

 

 

 

完了后自行注册个新会员试试,提示XXX ID已存在。就去数据库里检查Discuz和UC的用户表member,保持uid的递增值,改成一样大

Published in 网络

抱歉, 您的IP地址不在允许范围内, 或您的账号被禁用

如何修改这个提示

\source\language\lang_message.php
第238行

 

Published in 网络

关于CNERIS

CNERISYIF LINE公司的旗舰项目. 他是由IT行业不同区域的顶尖专家组成的. 我们的团队包括程序员,系统管理员,平面设计师, ERP集成服务。