GVKun编程网logo

从创建索引过程中内存变化来看 SQL Server 与 MySQL 的内存淘汰算法(创建索引的sql语句 mysql)

1

最近很多小伙伴都在问从创建索引过程中内存变化来看SQLServer与MySQL的内存淘汰算法和创建索引的sql语句mysql这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展Micr

最近很多小伙伴都在问从创建索引过程中内存变化来看 SQL Server 与 MySQL 的内存淘汰算法创建索引的sql语句 mysql这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展Microsoft SQL Server 2008 中 SQL Server 服务启动故障问题、mysql 启动报错Can''t connect to local MySQL server through socket ''/data/mysql/mysql/mysql.soc...、mysql 安装避坑指南 ,mysql 安装后不能启动, mysql 指定版本安装,mysql 5.7.39版本安装,mysql 5.7.36版本安装、Server.MapPath(".")、Server.MapPath("~")、Server.MapPath(@"")、Server.MapPath("/")。有什么区别?等相关知识,下面开始了哦!

本文目录一览:

从创建索引过程中内存变化来看 SQL Server 与 MySQL 的内存淘汰算法(创建索引的sql语句 mysql)

从创建索引过程中内存变化来看 SQL Server 与 MySQL 的内存淘汰算法(创建索引的sql语句 mysql)

在 sqlserver 中,几年之前就注意到一个现象:sqlserver 中对一个大表创建索引或者 rebuild 索引的过程中,会引起内存剧烈的动荡,究其原因为何,这种现象到底正不正常,是不是 sqlserver 内存管理存在缺陷?
另外,最近刚好想到跟 MySQL 对比一下类似操作引起的内存变化,测试 MySQL 会不会有类似问题,这里就简单写个代码验证一下这个问题。

 

数据库是一个非常依赖内存资源的软件系统,通过缓存数据(索引)到内存中,来改善数据物理访问的性能问题,

但是内存往往又不是无限大,或者足以容纳所有相关数据的容量,因此就存在内存页面的淘汰问题。
内存页的淘汰算法,多数是遵循 LRU 算法,LRU 是 Least Recently Used 的缩写,也即遵循 “最近做少使用” 的原则,选择最近最久未使用的页面予以淘汰。
这个算法表面上看起来没什么问题,如果有注意观察过在一台相对稳定的服务器上,给大表创建索引的过程,就会发现,整个过程中,buffer pool 会发生剧烈的动荡,创建索引的表会迅速侵入内存,挤走内存中原本的缓存。

由于 SQLServer 作为商业数据库,有关于它的页面淘汰算法的研究较少,仅仅是指导一个大概是遵循 LRU 的原则的,但是有没有在 LRU 的基础上进行改进或者优化,就不得而知,
但是 SQLServer 究竟有没有对该问题做改进或者优化?这里从一个索引的创建来管中窥豹,从侧面验证一下这个算法。

这里需要借助 SQLServer 中的一个变量值:Page life expectancy,
相信稍微熟悉 SQLServer 一点的人应该都知道这个参数代表的意义:内存页面的平均滞留时间,如果内存页面不断地被置换出去,这个值将会维持不变或者变得更小,因为新载入内存的页面在内存中停留的时间是较短的。
不知道有没有人注意过,在一台内存相对稳定的服务器上,对大表(1000W+)创建索引的时候,Page life expectancy 这个变量值会急转直下,这说明了什么?
大表创建索引粗略讲是读数据,然后写数据(索引树)的过程,这个过程中必然将相关的表读入内存,那么读入内存之后,他有没有淘汰内存中已有的数据?|
如果有,这明显是不合理的,创建索引只是创建索引,目的不是把内存中已有的热数据挤走,但是它还真的给内存中已有的热数据给挤走了。



反观 MySQL(Innodb 引擎),Redis 等数据库,都是基于优化的 LRU 或者 LFU 的原则淘汰页面。
MySQL 甚至可以人为地去调整这个 LFU 算法的一些参数值(innodb_old_blocks_pct,innodb_old_blocks_time),来达到优化内存淘汰的目的。
MySQL 中虽然没有类似于 PLE 的参数,但是可以从其他参数来间接推断,如果发生同样的操作,相关的表会不会挤走内存中的热数据.
这里基于 MySQL information_schema.innodb_buffer_pool_stats 这张表来作分析,其中这个表有两个字段,pages_made_young, pages_not_made_young ,这两个的变化代表这个新进入内存中的页面冷热变化情况。
同样的道理,如果内存中充斥着大量的热点数据,在对一个大表创建索引的过程中,并不希望因为创建索引而把热点数据挤出内存,究竟是不是这样的,同样在创建索引的过程中,观察一下这两个值的变化情况就可以了。



 
测试方法

这里通过循环,以 5 秒为间隔,连续输出 sqlserver 中的 Page life expectancy 这个变量的值,以及 MySQL 中的 pages_made_young 和 pages_not_made_young。

#coding=utf-8
import threading
import pymssql
import pymysql
from time import ctime,sleep
import datetime
import time

mssql_conn_conf = {''host'': ''***.***.***.***'', ''port'': 1433,  ''db'': ''master''}
mysql_conn_conf = {''host'': ''***.***.***.***'', ''port'': 3306, ''user'': ''root'', ''password'': ''***'', ''db'': ''information_schema''}

def mssql_ple():
    conn = pymssql.connect(host=mssql_conn_conf[''host''], port=mssql_conn_conf[''port''], database=mssql_conn_conf[''db''])
    cursor = conn.cursor()
    try:
        cursor.execute(" select cntr_value from sys.dm_os_performance_counters where object_name = ''MSSQL$SQL2014:Buffer Manager'' and counter_name = ''Page life expectancy'' ")
        row = cursor.fetchone()
        print(datetime.datetime.now().strftime(''%Y-%m-%d %H:%M:%S'')+ ''------>''+str(row[0]))
    except pymssql.Error as e:
        print("mysql execute error:", e)
    cursor.close()
    conn.close()

def mysql_memory():
    conn = pymysql.connect(host=mysql_conn_conf[''host''], port=mysql_conn_conf[''port''], database=mysql_conn_conf[''db''],user=mysql_conn_conf[''user''],password = mysql_conn_conf[''password''])
    cursor = conn.cursor()
    try:
        cursor.execute(''''''
                            SELECT 
                                SUM(pages_made_young) AS total_pages_made_young,
                                SUM(pages_not_made_young) AS total_pages_not_made_young
                            FROM
                            (
                                SELECT  pages_made_young, pages_not_made_young 
                                FROM information_schema.innodb_buffer_pool_stats
                            )t;
                        '''''')
        row = cursor.fetchone()
        print(datetime.datetime.now().strftime(''%Y-%m-%d %H:%M:%S'')+ ''------>''+''made_young:''+str(row[0])+'' not_made_young:''+str(row[1]))
    except pymssql.Error as e:
        print("mysql execute error:", e)
    cursor.close()
    conn.close()


if __name__ == ''__main__'':
    while 1>0:
        mysql_memory()
        time.sleep(5)

SQLServer 中的 PLE 变化测试

其实很容易观察,对于一台没有负载的服务器,因为没有新的内存页面载入内存,它的 Page life expectancy 值是递增的的,这个变量的单位是秒,间隔一秒,这个值会自动加 1。
一旦有新的页面载入内存,如果内存已经被用完,随着内存中已有的页面淘汰出去,这个值是会自动递减的,或者出现断崖式的下降。
这里运行上述脚本,打印出来当前服务器的 Page life expectancy 值,稍等一段时间后,在某个大表上创建出一个索引,再观察这个值的变化情况,

step1,对 DB01 库上的表进行反复的查询,使其载入内存(最近较多使用),左图是 DB01 库占用的内存情况,
step2,在 DB02 库上对一张大表创建索引,此过程中中会发现创建索引的表会迅速将已换成的数据挤出内存

 

MySQL 中的 pages_made_young 和 page_not_made_young 测试

因笔者事前重启过实例,因此 made_young 的值很小,关键要看,在某个大表上创建索引的过程中是不是会大量的 made_young 就行了。
这里可以看到,在创建索引开始之后,会出现大量的 not_made_young, 实际上这种效果是预期的,仅仅是创建索引,而不是顺带让当前这个大表的数据挤走热点数据(并没有大批量的 made_young)


这里也给出在 db02 上创建索引前后两个库占用的内存情况,虽然 db02 在其某个大表上创建索引之后占用了一定量的内存,但是这部分内存并非热数据,是随时可以被挤出 buffer pool 的,因为他们没有 page_made_young
step1,对 db01 库上的表进行的多次查询,使其载入内存,左图是 db01 库占用的内存情况,
step2,在 db02 库上对一张大表创建索引,此过程中中会发现不断地有大量的 page_not_made_young, 另外原本的 db01 库的内存并没有被大量的挤出。

 

总结
以个人浅薄的经历以及测试过程,发现 sqlserver 的内存管理,与 MySQL 相比,这一点做的确实不到位,与 MySQL 相比,其 buffer pool 管理本身的算法就存在问题,又是一个黑盒,也没有人为可以调整的可能性。

 


sqlserver 再不加油,真的就没人用了……

Microsoft SQL Server 2008 中 SQL Server 服务启动故障问题

Microsoft SQL Server 2008 中 SQL Server 服务启动故障问题

适用:本文只针对本人遇到的情况,其他情况解决方案有待。

版权:转载请注明出处。

 

问题:使用 Microsoft SQL Server 2008 的 SQL Server 配置管理器时,在 “SQL Server 服务” 中 “SQL Server(MSSQLSERVER)” 启动时,出现了 “由于登陆失败而无法启动” 的问题。

 

解决:

开始按钮 -- 控制面板 -- 管理工具 -- 服务 --SQL Server(MSSQLSERVER)-- 登陆 -- 登陆身份,选择 “本地系统账户”-- 常规 -- 启动

 

原因:

1. 可能是 Windows 系统密码更改过,设置 “本地系统账户”,则即使以后更改账户密码也依然可以正常启动。


原文链接: http://blog.csdn.net/poechant/article/details/5593783

mysql 启动报错Can''t connect to local MySQL server through socket ''/data/mysql/mysql/mysql.soc...

mysql 启动报错Can''t connect to local MySQL server through socket ''/data/mysql/mysql/mysql.soc...

1:首先mysql本地连接报错:

  Can''t connect to local MySQL server through socket ''/data/mysql/mysql/mysql.sock''(111)

  解决:

    1:删除 文件:/data/mysql/mysql/mysql.sock

  此时又会报错:Can''t connect to local MySQL server through socket ''/var/lib/mysql/mysql.sock'' (2)

  进入到目录:/data/mysql2/bin/

    使用命令:mysqld start

    此时报错:[ERROR] Too many arguments (first extra is ''start'')

    于是将命令修改:mysqld --user=mysql

感谢:

  https://www.cnblogs.com/invban/p/5824796.html

  https://blog.csdn.net/u010416101/article/details/80490536

 

 

 

 

2:19年7月4日,mysql不是自己安装的,也不晓得是怎么安装的.在启动时依然报这个错误,按照前面的方法还是解决不了.

然后我又使用如下命令,启动依然报错

./mysqld --defaults-file=/data/mysql/mysql01/my.cnf --basedir=/data/mysql/mysql01 --datadir=/data/mysql/mysql01/data  --user=zabbix

  

 

mysql 安装避坑指南 ,mysql 安装后不能启动, mysql 指定版本安装,mysql 5.7.39版本安装,mysql 5.7.36版本安装

mysql 安装避坑指南 ,mysql 安装后不能启动, mysql 指定版本安装,mysql 5.7.39版本安装,mysql 5.7.36版本安装

MysqL 安装后不能启动,报错如下:请参照本说明第7条的办法解决。
MysqLd.service: Control process exited, code=exited status=1
Please read “Security” section of the manual to find out how to run MysqLd as root

如果MysqL安装遇到了错误如下:请参照第5条的办法解决。
All matches were filtered out by modular filtering for argument: MysqL-community-server
Error: Unable to find a match: MysqL-community-server
具体⽇志错误日志文件:在MysqL 配置⽂件 /etc/my.cnf 中有设置。
log-error=/var/log/MysqLd.log
pid-file=/var/run/MysqLd/MysqLd.pid



1.检查CentOS是否有系统自带的MysqL

yum list installed | grep MysqL

2.如果存在系统自带的MysqL及依赖,则通过 yum remove 将其卸载
卸载后记得执行以下命令删除数据库文件,(删除数据库前请自己确认是否有重要数据库文件!)

 rm -rf /var/lib/MysqL  #这个是centos下的数据库文件位置


3.CentOS中下载rpm包,并安装本地MysqL源

下载rpm包:yum localinstall MysqL80-community-release-el7-3.noarch.rpm

通过 yum localinstall 安装MysqL源,可以帮助我们解决本地rpm包的依赖问题。

最后,验证是否安装成功:yum repolist all | grep MysqL
wget https://dev.MysqL.com/get/MysqL80-community-release-el7-3.noarch.rpm
rpm -ivh MysqL80-community-release-el7-3.noarch.rpm
 yum repolist all | grep MysqL
4.修改默认安装版本为5.7

从上面的图片,我们可以看到,默认是MysqL 8.0可用,我们若想安装MysqL 5.7,则需启用5.7。接下来通过直接修改配置文件来设置启用。

vim /etc/yum.repos.d/MysqL-community.repo

输入上面的命令,在编辑界面,先输入 i 进入编辑模式,将8.0的 enabled 设置为0,将5.7的 enabled 设置为1

5.安装

yum install -y MysqL-community-server

如果遇到了错误
All matches were filtered out by modular filtering for argument: MysqL-community-server
Error: Unable to find a match: MysqL-community-server

解决方法

sudo yum module disable MysqL

重复 yum install -y MysqL-community-server

6.遇到了错误

Public key for MysqL-community-client-5.7.38-1.el7.x86_64.rpm is not installed. Failing package is: MysqL-community-client-5.7.38-1.el7.x86_64

解决方法

sudo rpm --import https://repo.MysqL.com/RPM-GPG-KEY-MysqL-2022
或者这样,我是这样解决的:
yum install MysqL-community-server --nogpgcheck



检查

sudo systemctl status MysqLd

7.启动

sudo systemctl start MysqLd
如果无法启动,可能是以前安装其他版本MysqL有文件残留
先卸载MysqL
yum remove MysqL
 yum -y remove MysqL*
然后删除: rm -rf /var/lib/MysqL          #删除数据库前请自己确认是否有重要数据库文件!
重新运行安装命令:
yum install MysqL-community-server --nogpgcheck
service MysqLd start
再次启动服务成功!

8.查看临时密码

sudo grep 'temporary password' /var/log/MysqLd.log

9.更改密码
MysqL> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!';

10.配置
MysqL_secure_installation


ps.直接安装最新版:
sudo dnf -y install @MysqL
登录 创建root管理员和密码
    MysqLadmin -u root password 123456
    登录: MysqL -u root -p输入密码即可。
    忘记密码
    service MysqLd stop;
    MysqLd_safe --user=root --skip-grant-tables;
    这一步骤执行的时候不会出现新的命令行,你需要重新打开一个窗口执行下面的命令
    MysqL -u root;
    use MysqL ;
    update user set password=password("123456") where user="root";
    flush privileges;
远程访问 开放防火墙的端口号MysqL
    增加权限:MysqL库中的user表新增一条记录Host为“%”,User为“root”。
    
一般开发测试直接把防火墙关闭
su  root
service iptables stop  #关闭防火墙
service iptables status  #验证是否关闭
chkconfig iptables off  #关闭防火墙的开机自动运行
chkconfig –list |  grep  iptables  #验证防火墙的开机自动运行
vim  /etc/sysconfig/selinux  # 禁用selinux,将SELINUX=disabled

授权用户可以从远程登陆
    grant all PRIVILEGES on *.* to root@'%'  identified by '123456替换自己的密码';
    flush privileges ;



Server.MapPath(

Server.MapPath(".")、Server.MapPath("~")、Server.MapPath(@"")、Server.MapPath("/")。有什么区别?

谁能解释Server.MapPath("."),Server.MapPath("~")和之间Server.MapPath(@"\")的区别Server.MapPath("/")

答案1

小编典典

Server.MapPath 指定映射 到物理目录 的相对或虚拟路径。

  • Server.MapPath(".")1返回正在执行的文件(例如 aspx)的当前物理目录
  • Server.MapPath("..")返回父目录
  • Server.MapPath("~")返回应用程序根目录的物理路径
  • Server.MapPath("/")返回域名根目录的物理路径(不一定和应用的根目录相同)

一个例子:

假设您将网站应用程序 ( http://www.example.com/) 指向

C:\Inetpub\wwwroot

并在

D:\WebApps\shop

例如,如果您调用Server.MapPath()以下请求:

http://www.example.com/shop/products/GetProduct.aspx?id=2342

然后:

  • Server.MapPath(".")1次退货D:\WebApps\shop\products
  • Server.MapPath("..")返回D:\WebApps\shop
  • Server.MapPath("~")返回D:\WebApps\shop
  • Server.MapPath("/")返回C:\Inetpub\wwwroot
  • Server.MapPath("/shop")返回D:\WebApps\shop

如果 Path 以正斜杠 ( /) 或反斜杠 ( \) 开头,则MapPath()返回路径,就好像 Path 是完整的虚拟路径一样。

如果 Path 不以斜杠开头,则MapPath()返回相对于正在处理的请求的目录的路径。

注意:在 C# 中,@是逐字字面字符串运算符,表示字符串应该“按原样”使用,而不是为转义序列处理。

脚注

  1. Server.MapPath(null)也会Server.MapPath("")产生这种效果。
  2. MapPath(string virtualPath)调用以下内容:
public string MapPath(string virtualPath){    return this.MapPath(VirtualPath.CreateAllowNull(virtualPath));}

MapPath(VirtualPath virtualPath)依次调用MapPath(VirtualPath virtualPath, VirtualPath baseVirtualDir, bool allowCrossAppMapping)其中包含以下内容:

//...if (virtualPath == null){    virtualPath = VirtualPath.Create(".");}//...

所以如果你打电话MapPath(null)or MapPath(""),你实际上是在打电话MapPath(".")

关于从创建索引过程中内存变化来看 SQL Server 与 MySQL 的内存淘汰算法创建索引的sql语句 mysql的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Microsoft SQL Server 2008 中 SQL Server 服务启动故障问题、mysql 启动报错Can''t connect to local MySQL server through socket ''/data/mysql/mysql/mysql.soc...、mysql 安装避坑指南 ,mysql 安装后不能启动, mysql 指定版本安装,mysql 5.7.39版本安装,mysql 5.7.36版本安装、Server.MapPath(".")、Server.MapPath("~")、Server.MapPath(@"")、Server.MapPath("/")。有什么区别?等相关知识的信息别忘了在本站进行查找喔。

本文标签: