Spike oversold sql

Article discussions

Transfer from mysql commodity stocks deduction summary problem

Like spike problem has been relatively hot issues of web domain, an ultra high concurrency site needs to be considered from the product, front-end optimization, site considered all aspects of the deployment and back-end services. mysql can write withstood the pressure is certain, highly concurrent web site, you need to control the pressure before the data persistence, rather than all of the data service requests fell on this layer. Today I discuss in this article do not question the overall design of the spike (I did not have this qualification), how in the case of the flow rate has been controlled, how to use mysql more secure and efficient solution to this problem we are discussing.

From the Internet we can see a variety of implementations, and now discuss each of these programs and their advantages and disadvantages and misunderstanding.

Common written safety and efficiency analysis

We assume schema merchandise table is like this:

CREATE TABLE `goods` (  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '自增id',  `name` varchar(256) NOT NULL DEFAULT '' COMMENT '商品名称',  `available` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '库存剩余量',  `stock` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '总库存量',  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品表'

Is set to field an unsigned solve

num = select available from goods where id = xx ;if(num > 0){   affectRows = udpate goods set available = available - 1 where id = xx ;   if(affectRows == 1){       return ok ;   }else{       return fatal ;   }}

Interpretation Solution

This approach everyone's idea is that we will Inventory field is set to unsigned types, so that when the field is set to a negative inventory when an error in sql mysql will execute when it affectRow would be 0 or can capture the exception, thus data security under concurrency.

This code is actually dangerous, because in different versions of mysql and configuration, the performance of this code is completely different. The specific situation three different results occur:

  • 1. code to run properly, being given time to perform update
  • 2. The code is executed resulting in a final -1
  • 3. After final update operations, available into a large number of

Why is there three cases of it?

I want to calculate addition and subtraction method when the computer is started learning computer learning are spoken.

思考一下,无符号2 减去 无符号3 在计算机中的运算是什么样的?2 - 3 = 2 + (-3)假设我们的计算机是4位的,2的补码表示:0010,-3的补码表示为1011那么加和的结果是00101011 + ------1111 =1111解释为有符号数是多少呢? -11111解释为无符号数是多少呢? 15

So?
If mysql without any treatment, then your results will not be unsigned subtraction error, eventually you figure out the stock is still a very large value (terrible).
But fortunately later versions mysql help you do this thing (I do not know specifically which version), so if it is done mysql unsigned detected, and if the result of the subtraction is negative, will complain that this is most people look forward to the results.
-1 this case you need to set up some sqlmode, which also occur in the case.

Solution summary

  • Many people use this approach when no problem, it only shows that may be coincidental, but for the business code, it can not rely on luck, you need to eliminate uncertainty, reduce migration costs.
  • If you want to use this approach, you put your hard msyql figure out the appropriate version and configuration, unsigned determine what the results will appear in the version where you are.

select for update

Interpretation Solution

Read when he started to add one row is a common way to lock him online, specifically to achieve the following:

begin tran ;num = select avaliable from goods where id = xxx for update;if (num >= 0){   affectNum = udpate goods set available = available - 1 where id = xx ;   commit ;   return affectNum ;}else{   rollback ;}

The solution is added when the user reads the corresponding data row locks to ensure data update themselves when the row has not been changed by another process. All written requests an exclusive lock and lock will be blocked.
Think about this situation, A execution process, occurs crash situation led to commit / rollback request was not sent to mysqlserver, then all requests will lock wait.

Solution summary

  • Low flow can use this approach to ensure the security of data

  • Poor performance

    , Sending an average of four times mysql request, and it will cause all similar requests lock wait.

    common problem

  • You need to select for udpate block of code in the transaction explicitly specify otherwise will not work. Many users are granted artificially select for update can directly add exclusive lock

  • Exclusive lock release is not released after the completion of the rollback / commit action, not operating in the update. mysql innodb perform two-phase locking protocol, phase lock only lock, unlock unlocking phase only.

The use of the transaction, after the first check and then write the check to ensure that no problem

Interpretation Solution

This time available to signed types, solving a problem of program

begin tran ;num = select available from goods where id = xx ;if(num > 0){   //实际需要关心这里的返回值,这里不考虑   udpate goods set available = available - 1 where id = xx ;   num_afterupdate = select available from goods where id = xx ;   if(num_afterupdate < 0 ){       rollback ;   }else{       commit ;   }}

This solution distinction in the first approach is that, plus the transaction, available types of changes, using the update confirmation form, try to solve the problem.

We all know that the database transaction isolation level there are four kinds:
RU, RC, RR, Serializable.
The most common pattern is innodb in RR can ensure repeatable read, meaning inside the same transaction, the results of multiple reads of the same. So the last reading for the RR isolation level is actually ineffective.
In RC mode, the code is available, each request to ensure that the process does not own super-fat.

Solution summary

  • RR, RC mode inconsistent results under .RR not guarantee security, RC can.
  • Performance is not high, a service request to mysql conversion is 1: 5.
  • This solution like a grandmother to lock the door, always locked himself in the end do not trust not, check back a few steps away, in fact, sometimes it is futile.

update query statement to increase available

Interpretation Solution

udpate goods set available = available - 1 where id = xx and available - 1 >= 0 ;

This statement If so, then he must be the performance of the method mentioned above lock in the best.
The key phrase is concentrated in how proof of safety.
We all know the case of update operations for id primary key index, the data will be added to the line lock.
In fact, the process update operation after a first check inside mysql is changed, if the process is atomic, you can guarantee the update statement is serial, then we look at the process of the update statement within mysql.
update execution process

Another myth is that everyone there is not a single statement transaction, in fact, is a single sql transaction.
So for the statement above, follow the same two-phase locking protocol.
update process executed, the query will go to meet the conditions of the line and lock, the lock is innodb do, then we can guarantee that after the transaction is finished executing other transactions must wait to obtain a lock, this time to get the latest data.

Solution summary

  • Statement security, efficiency best (in my knowledge)

Set using stock rather than deductions stock

These days I have a similar article almost doubled again, the only criticism I see on a practice that I do not have that approach is idempotent nature.

  • The so-called idempotency is, a user with access to the same connection does not produce side effects. For example, on a program, if recording user actions and deductions stock not atomic, then the problem is likely to arise, inventory deductions successful, but the user record fails, then the user to repeat the request, there will be many times reduction of inventory problems.

So their solution is that, instead of using set deduction, as follows:

num_old = select available from goods where id = xx and available >= 1 ;num_new = num_old - 1 ;update goods set num=num_new where id=xx and num=num_old ;

This code is safe, using the concept of optimism to complete the operation.

to sum up

  • The above practice, the last two are relatively safe, but you still have to set the field of inventory unsigned, on whether idempotent, combined with a request to look to see, not a single piece of code deductions.
  • Seriously is a learning process, can only seriously these concepts clear. If you need to fully understand the content, you may need to lock mysql, transactions, mvcc these concepts do some prep.
  • Thanks to the work process of small efforts of its partners, allowing us to track down the problem more clearly.

Guess you like

Origin www.cnblogs.com/hitomeng/p/12369961.html