
MySQL(发音为"myesscueel",不是"mysequel")是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理。由于MySQL是开放源代码的,因此任何人都可以在GeneralPublicLicense的许可下下载并根据个性化的需要对其进行修改。MySQL因为其速度、可靠性和适应性而备受关注。大多数人都认为在不需要事务化处理的情况下,MySQL是管理内容最好的选择。MySQL关系型数据库于1998年1月发行第一个版本。它使用系统核心提供的多线程机制提供完全的多线程运行模式,提供了面向C、C++、Eiffel、Java、Perl、PHP、Python以及Tcl等编程语言的编程接口(APIs),支持多种字段类型并且提供了完整的 *** 作符支持查询中的SELECT和WHERE *** 作。MySQL开发组计划于2001年中期公布MySQL40版本。在这个版本中将有以下新的特性被提供:新的表定义文件格式、高性能的数据复制功能、更加强大的全文搜索功能。在此之后,MySQL开发着希望提供安全的数据复制机制、在BeOS *** 作系统上的MySQL实现以及对延时关键字的定期刷新选项。随着时间的推进,MySQL将对ANSI92/ANSI99标准完全兼容。MsSql---->MicroSoftSqlServer,需要money,而且很多呢。(大型项目用,大型网站用)MySql---->免费的。速度快。可以用于小型项目。mysql数据库和oracle的区别和选择:LAMP大会的时候我跟Yahoo的一个技术高管聊的时候,我问他Yahoo在选择MySQL还是Oracle的时候是怎么考虑,他的答案令我非常惊讶。他说大部分的时候我们是会用MySQL的,因为它的性能已经达到我们的要求。但是什么时候我们会选用Oracle呢,就是当我们需要存储收费用户的数据的时候。我就问为什么,难道Oracle比MySQL稳定吗他说,这个倒没有特别考虑。关键是如果使用Oracle的话,当出现问题的时候我们可以找到负责人,Oracle会负责事故的处理,但是如果用MySQL的话,我们找谁去
多线程连接数据库的连接池类:
public static class ConnectionPool
{
private static object locker = new object();
private static Dictionary<string, SqlConnection> Connections = null;
public static SqlConnection GetConnection<T>() where T : class, new()
{
string databaseName = NACommonExtensionsGetDatabaseName<T>();
if (stringIsNullOrEmpty(databaseName))
return null;
if (Connections == null)
{
lock (locker)
{
Connections = new Dictionary<string, SqlConnection>();
}
}
string connKey = FindFreeSqlConnection(databaseName);
if (connKey != null)
return Connections[connKey];
else
{
string strconn = NACommonExtensionsGetConnectionString<T>();
int poolSize = NACommonExtensionsGetConnectionPoolSize<T>();
lock (locker)
{
for (int i = 0; i < poolSize; ++i)
{
SqlConnection conn = new SqlConnection(strconn);
connOpen();
ConnectionsAdd(databaseName + "_" + iToString(), conn);
connClose();
}
}
return Connections[FindFreeSqlConnection(databaseName)];
}
}
private static string FindFreeSqlConnection(string databaseName)
{
IEnumerable<string> connKeys = ConnectionsKeysWhere(item => itemStartsWith(databaseName));
if (connKeys != null && connKeysCount() > 0)
{
foreach (string key in connKeys)
{
if (Connections[key]State == ConnectionStateClosed)
return key;
}
}
return null;
}
}
附加上其中用到的三个方法:
internal static int GetConnectionPoolSize<T>() where T : class, new()
{
string database = GetDatabaseName<T>();
string[] poolSizeArray = ConfigurationManagerAppSettings["ConnectionsPoolSize"]Split('|');
if (poolSizeArray != null)
{
foreach (string sizeItem in poolSizeArray)
{
string[] sizeItemArray = sizeItemSplit(':');
if (database == sizeItemArray[0])
return intParse(sizeItemArray[1]);
}
}
return 50;
}
public static string GetConnectionString<T>() where T : class, new()
{
string tableName = GetTableName<T>();
string[] databaseArray = ConfigurationManagerAppSettings["DatabaseArray"]Split('|');
if (databaseArray != null)
{
foreach (string database in databaseArray)
{
string tableNameList = ConfigurationManagerAppSettings[database];
string[] tables = ConfigurationManagerAppSettings[database]Split('|');
if (tables != null && tablesLength > 0)
if (tablesContains(tableName))
return ConfigurationManagerConnectionStrings[database]ConnectionString;
}
}
return stringEmpty;
}
public static string GetDatabaseName<T>() where T : class, new()
{
string tableName = GetTableName<T>();
string[] databaseArray = ConfigurationManagerAppSettings["DatabaseArray"]Split('|');
if (databaseArray != null)
{
foreach (string database in databaseArray)
{
string tableNameList = ConfigurationManagerAppSettings[database];
string[] tables = ConfigurationManagerAppSettings[database]Split('|');
if (tables != null && tablesLength > 0)
if (tablesContains(tableName))
return database;
}
}
return stringEmpty;
}
你的提问就有问题
当你的程序不管是不是多线程的
获得到一个数据库连接是 数据库会把这个连接标记为繁忙 当其他程序访问时它会返回另外空闲的连接
连接个数是有限的 如果一直不释放连接 数据库就会告诉你连接已经使用完了
这里和线程安全有何关系呢? 线程安全和数据库 *** 作没有直接关系
在MySQL 80 之前, 我们假设一下有一条烂SQL,
mysqlselect from t1 order by rand() ;
以多个线程在跑,导致CPU被跑满了,其他的请求只能被阻塞进不来。那这种情况怎么办?
大概有以下几种解决办法:
设置max_execution_time 来阻止太长的读SQL。那可能存在的问题是会把所有长SQL都给KILL 掉。有些必须要执行很长时间的也会被误杀。
自己写个脚本检测这类语句,比如order by rand(), 超过一定时间用Kill query thread_id 给杀掉。
那能不能不要杀掉而让他正常运行,但是又不影响其他的请求呢?
那mysql 80 引入的资源组(resource group,后面简写微RG)可以基本上解决这类问题。
比如我可以用 RG 来在SQL层面给他限制在特定的一个CPU核上,这样我就不管他,让他继续运行,如果有新的此类语句,让他排队好了。
为什么说基本呢?目前只能绑定CPU资源,其他的暂时不行。
那我来演示下如何使用RG。
创建一个资源组user_ytt 这里解释下各个参数的含义,
type = user 表示这是一个用户态线程,也就是前台的请求线程。如果type=system,表示后台线程,用来限制mysql自己的线程,比如Innodb purge thread,innodb read thread等等。
vcpu 代表cpu的逻辑核数,这里0-1代表前两个核被绑定到这个RG。可以用lscpu,top等列出自己的CPU相关信息。
thread_priority 设置优先级。user 级优先级设置大于0。
mysqlmysql> create resource group user_ytt type = user vcpu = 0-1 thread_priority=19 enable;Query OK, 0 rows affected (003 sec)
RG相关信息可以从 information_schemaresource_groups 系统表里检索。
mysqlmysql> select from information_schemaresource_groups;+---------------------+---------------------+------------------------+----------+-----------------+| RESOURCE_GROUP_NAME | RESOURCE_GROUP_TYPE | RESOURCE_GROUP_ENABLED | VCPU_IDS | THREAD_PRIORITY |+---------------------+---------------------+------------------------+----------+-----------------+| USR_default | USER | 1 | 0-3 | 0 || SYS_default | SYSTEM | 1 | 0-3 | 0 || user_ytt | USER | 1 | 0-1 | 19 |+---------------------+---------------------+------------------------+----------+-----------------+3 rows in set (000 sec)
我们来给语句select guid from t1 group by left(guid,8) order by rand() 赋予RG user_ytt。
mysql> show processlist;+-----+-----------------+-----------+------+---------+-------+------------------------+-----------------------------------------------------------+| Id | User | Host | db | Command | Time | State | Info |+-----+-----------------+-----------+------+---------+-------+------------------------+-----------------------------------------------------------+| 4 | event_scheduler | localhost | NULL | Daemon | 10179 | Waiting on empty queue | NULL || 240 | root | localhost | ytt | Query | 101 | Creating sort index | select guid from t1 group by left(guid,8) order by rand() || 245 | root | localhost | ytt | Query | 0 | starting | show processlist |+-----+-----------------+-----------+------+---------+-------+------------------------+-----------------------------------------------------------+3 rows in set (000 sec)
找到连接240对应的thread_id。
mysqlmysql> select thread_id from performance_schemathreads where processlist_id = 240;+-----------+| thread_id |+-----------+| 278 |+-----------+1 row in set (000 sec)
给这个线程278赋予RG user_ytt。没报错就算成功了。
mysqlmysql> set resource group user_ytt for 278;Query OK, 0 rows affected (000 sec)
当然这个是在运维层面来做的,我们也可以在开发层面结合 MYSQL HINT 来单独给这个语句赋予RG。比如:
mysqlmysql> select /+ resource_group(user_ytt) /guid from t1 group by left(guid,8) order by rand()8388602 rows in set (4 min 4609 sec)
RG的限制:
Linux 平台上需要开启 CAPSYSNICE 特性。比如我机器上用systemd 给mysql 服务加上
systemctl edit mysql@80 [Service]AmbientCapabilities=CAP_SYS_NICE
mysql 线程池开启后RG失效。
freebsd,solaris 平台thread_priority 失效。
目前只能绑定CPU,不能绑定其他资源。
以上就是关于python 访问 Mysql 数据库,是多线程好还是多进程好全部的内容,包括:python 访问 Mysql 数据库,是多线程好还是多进程好、多线程 连接数据库,C#多线程写数据库、请教多线程数据库程序如何保证线程安全等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)