go sql.stmt query 发生了一个NULL值,所以发现了error, 发现服务不停的初始化sql stmt, 导致连接数过多,服务就变得很慢。

首先,我在初始化的之前,要判断这个是否是NULL(见下面列表5)导致的,并非是sql请求出错。 我为啥要全局变量保存sql.Stmt, 导致要处理sql.Stmt出错。

go prepare 的问题(见下面列表2)导致数据库连接数太大,所以我使用全局变量保存用prepare 方法创建的sql.Stmt(见下面列表3,但是根据列表2,其实没有解决问题,  除非列表4),同时就要考虑出现错误的时候重新初始化。初始化的时候就涉及到互斥的问题, 那就要加锁(见下面列表1)。但是锁不能乱加,因为后台是要支持并发的,如果都加写锁。就会响应很慢了。所以要加读锁,重新初始化的时候,解读锁加写锁,但是加锁的作用是线程与线程之前,并非是for 语句,所以你如果有for语句,要考虑是否要break。加锁的范围不要很大,因为太大不好控制(出现嵌套加锁,其实无关的代码占用了释放锁的时间),而且你要释放锁


1. 读写锁

http://www.alexedwards.net/blog/understanding-mutexes

func (rw *RWMutex) Lock()

Lock locks rw for writing. If the lock is already locked for reading or writing, Lock blocks until the lock is available. To ensure that the lock eventually becomes available, a blocked Lock call excludes new readers from acquiring the lock.

不能读也不能写

Unlock unlocks rw for writing. It is a run-time error if rw is not locked for writing on entry to Unlock.

As with Mutexes, a locked RWMutex is not associated with a particular goroutine. One goroutine may RLock (Lock) an RWMutex and then arrange for another goroutine to RUnlock (Unlock) it.

We can achieve this using RWMutex, a reader/writer mutual exclusion lock which allows any number of readers to hold the lock or one writer.  ---  可以有多个读操作,或者一个写操作。

如果不加对应的锁,然后解锁的话会引发错误。会引发错误。

但是已经加了一个读锁,没有解锁又加一个写锁,会造成死锁。就是挂住,程序不会动了。

有的会打印: fatal error: all goroutines are asleep - deadlock!


2. 使用sql prepare不能很好复用,它可能自己重新生成prepare语句,会导致泄露。

http://go-database-sql.org/prepared.html

Here’s how it works:

  1. When you prepare a statement, it’s prepared on a connection in the pool.
  2. The Stmt object remembers which connection was used.
  3. When you execute the Stmt, it tries to use the connection. If it’s not available because it’s closed or busy doing something else, it gets another connection from the pool and re-prepares the statement with the database on another connection.

Because statements will be re-prepared as needed when their original connection is busy, it’s possible for high-concurrency usage of the database, which may keep a lot of connections busy, to create a large number of prepared statements. This can result in apparent leaks of statements, statements being prepared and re-prepared more often than you think, and even running into server-side limits on the number of statements.


3. sql.Stmt 是可并发的

type Stmt

type Stmt struct {
// contains filtered or unexported fields
}

Stmt is a prepared statement. A Stmt is safe for concurrent use by multiple goroutines.

http://go-database-sql.org/retrieving.html


4.  go 1.4 fixed bug.

prepare stmt

http://studygolang.com/articles/1795


5. 数据表里默认值为NULL

http://www.cnblogs.com/javathread/archive/2012/01/05/2634719.html

11. 尽可能的使用 NOT NULL

除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL。这看起来好像有点争议,请往下看。

首先,问问你自己“Empty”和“NULL”有多大的区别(如果是INT,那就是0和NULL)?如果你觉得它们之间没有什么区别,那么你就不要使用NULL。(你知道吗?在 Oracle 里,NULL 和 Empty 的字符串是一样的!)

不要以为 NULL 不需要空间,其需要额外的空间,并且,在你进行比较的时候,你的程序会更复杂。 当然,这里并不是说你就不能使用NULL了,现实情况是很复杂的,依然会有些情况下,你需要使用NULL值。

下面摘自MySQL自己的文档:    

“NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”      

一个NULL引发的血案的更多相关文章

  1. Replication的犄角旮旯(六)-- 一个DDL引发的血案(上)(如何近似估算DDL操作进度)

    <Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...

  2. 一个字母引发的血案 java.io.File中mkdir()和mkdirs()

    一个字母引发的血案 明天开始放年假了,临放假前有个爬虫的任务,其中需要把网络图片保存到本地,很简单,马上写完了代码: //省略部分代码... Long fileId= (Long) data.get( ...

  3. SQL实战——04. 查找所有已经分配部门的员工的last_name和first_name以及dept_no (一个逗号引发的血案)

    查找所有已经分配部门的员工的last_name和first_name以及dept_noCREATE TABLE `dept_emp` (`emp_no` int(11) NOT NULL,`dept_ ...

  4. Replication的犄角旮旯(七)-- 一个DDL引发的血案(下)(聊聊logreader的延迟)

    <Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...

  5. 【原创】经验分享:一个Content-Length引发的血案(almost....)

    前言 上周在工作中遇到一个问题,挺有意思,这里记录一下.上周在工作中遇到一个问题,挺有意思,这里记录一下.标题起的很唬人,这个问题差点引发血案,花哥还是很严谨的一个人,后面备注了almost.... ...

  6. 一个链接引发的血案---------服务器 IO及网络流量暴涨解决历程

    在这里介绍一次因为更改网站地址而引发服务器IO读取速度,网络流入流出速度暴涨10倍的解决经历. 环境:Ubuntu + Nginx + php-cgi + Wordpress 事情是这样的,现在网站使 ...

  7. 一个null引发的错误

    写程序时,发生一个unrecognized selector的错误,很显然,这是一个经典错误,运行时找不到可调用的方法. 系统提示的reason是 -[NSNull length] 错误 经过查找,原 ...

  8. String属于“假引用类型”,代码为证(一个String引发的血案...)

    一直以为String是引用类型,今天写了个浅拷贝的测试,发现String有基本类型的特征. class A{ public int a = 555; } class User implements C ...

  9. 【转】Druid连接池一个设置引发的血案

    https://my.oschina.net/haogrgr/blog/224010 今天在一台配置很低的机器上运行批量更新的程序~~~ 大概跑了三十分钟~~~这配置~~~这程序~~~ 然后华丽丽的报 ...

随机推荐

  1. hdu1874 最短路模板题

    之所以做了第二道模板题还要写是因为发现了一些自己的问题 用的是dij 最简单的松弛 需要注意的地方是松弛的时候 判断dis[i]<dis[w]+tance[w][i]时 还要再判断 vis[i] ...

  2. FlowVisor 安装

    参考:Github-FlowVisor-wiki 第一步 添加公钥: 命令: $ wget http://updates.onlab.us/GPG-KEY-ONLAB $ sudo apt-key a ...

  3. 使用ngrok

    使用ngrok让微信公众平台通过80端口访问本机 首先声明我是用java-tomcat来研究微信公众平台的. 微信公众平台要成为开发者,需要填写接口配置信息中的“URL”和“Token”这两项(参见: ...

  4. Nginx配置文件详细说明[转]

    在此记录下Nginx服务器nginx.conf的配置文件说明, 部分注释收集与网络. #运行用户user www-data;    #启动进程,通常设置成和cpu的数量相等worker_process ...

  5. HybridTime - Accessible Global Consistency with High Clock Uncertainty

    Amazon's Dynamo [9] and Facebook's Cassandra [13], relax the consistency model,and offer only eventu ...

  6. vm设置静态ip

    1. 进入虚拟linux系统中,vim /etc/sysconfig/network-scripts/ifcfg-eth0,里面保留以下内容即可: DEVICE=eth0 //使用的网卡标识 BOOT ...

  7. StringUtil

    package per.son.utils; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.js ...

  8. Python 虚拟环境Virtualenv

    本人也是Python爱好者,众所周知,Python扩展多,每次为了测试,安装各种各样的扩展,这样导致本地的Python环境非常混乱,就有人想到搞个隔离环境  和 本地环境没有关系,随时可以删除这个隔离 ...

  9. 局部变量、结构体和main函数

    在函数中定义的变量称为自动局部变量.因为每次调用该函数时,它们都自动“创建”,并且它们的只对于函数来说是局部的,局部对象的变量都会默认为空.局部变量的值只能在定义该变量的函数中访问,不能从函数之外访问 ...

  10. 介绍UDF,以及完成大小写的转换

    一:概述 1.UDF 用户自定义函数,用java实现自定义的需求 2.UDF的类型 udf:一进一出 udaf:多进一出 udtf:一进多出 3.udf的实现步骤 继承UDF类 实现evaluate的 ...