mysql combat 28 | What are separate read and write pit?

In the previous article, I introduce you to the main structure, and a multi-switching process from the. Today, we continue to talk about a master multi-slave scenarios architecture: separate read and write, and how to deal with the primary and separate read and write latency problems caused.

A main we mentioned in the previous article and more from the structure, in fact, separate read and write the basic structure. Here, then this picture I posted up, allowing you to understand.


                                                       1 the basic structure of FIG separate read and write

The main objective is to separate read and write the main library sharing pressure. FIG 1 is a configuration of the client (client) active load balancing, database connection information will generally be placed in this mode the client layer connection. In other words, by the client to select the back-end database queries.

Another architecture is that there is a proxy between the intermediate layer agent and MySQL client, the client is only connected proxy, the proxy route request type and the distribution request according to the context of the decision.


                                                     2 with separate read and write architecture proxy in FIG.

Next, we look at the client direct and write with a separate proxy architecture, which have their own characteristics.
  1. The client direct scheme, because the less one proxy forwards, so a little bit better query performance, and the overall structure is simple, troubleshoot problems more easily. But this program, due to understand the back-end deployment details, so standby switching, database migration and other operations in the event of the time, the client will be perceived, and the need to adjust the database connection information.
    You might think that the client too much trouble, a lot of redundant information, ugly architecture. In fact, it may not, in general such a framework must be accompanied by a responsible for managing the back-end components, such Zookeeper, try to make the business end only focus on business logic development.
  2. Architecture with a proxy, and client more friendly. The client does not need to focus on the details of the back-end, connection maintenance, back-end information and maintenance work is done by the proxy. But this is the case, the requirements of the back-end maintenance team will be higher. Moreover, proxy also need to have high-availability architecture. Therefore, the overall band proxy architecture is relatively complex.

Understand the pros and cons of these two programs, the specific choice of which depends on the ability to program a database provided by the team. But for the moment, the trend is toward the direction of proxy architecture with the development.

However, regardless of which architecture to use, you will encounter a problem we have to discuss today: Since there may be a delay from the master, the client sends a query executing the update immediately after a transaction, if the query is selected from a library of words, it is possible just read the state before the transaction date.

This "in an expired state of the system will read from the library" phenomenon, in this article, we would call "expire read."

We have said several possible reasons for the delay standby, and the corresponding optimization strategies, but still can not master the delay from 100% to avoid.

In either configuration, the client wants the query results from the data library, check with the main library data result is the same.

Next, we'll discuss how to deal expired reading problems.

Here, the disposal of obsolete programs I first read the article involved in the summary is here to help you better understand and grasp the full knowledge of the context. These programs include:

  • Forced to go the main library programs;
  • sleep program;
  • Analyzing standby program without delay;
  • Semi-sync with the program;
  • Primary database programs and other sites;
  • Etc. GTID program.

Forced to go the main library program

Forced to go is actually the main library program, the queries do classification. Under normal circumstances, we can query requests into such categories:

  1. For the need to get the latest result of the request, forcing sends it to the main library. For example, on a trading platform, the seller after release of goods, is about to return to the main page to see if the release of goods successful. Well, this request needs to get the latest results, it must take the main library.
  2. For a request to read the old data can only be sent to the library. In this trading platform, buyers to visit the shop page, even a few seconds later to see the latest release of goods, it is also acceptable. So, such requests can go from the library.

You might say that this program is not a bit afraid of difficulties and tricky means, but in fact this program is the most used.

Of course, the biggest problem with this scheme is that sometimes you'll run into "all queries can not be expired read" demands such as some financial business. In this case, you have to give up separate read and write, read and write all the pressure in the main library, equivalent to give up scalability.

So the next topic we discuss is: can read and write support of separate scenes, which expired reading programs to address and analyze the advantages and disadvantages of each program.

Sleep program

After the primary database updates, read from the library to sleep before it. Specific program is similar to the implementation of a select sleep (1) command.

Assuming that this program is, in most cases the primary and delay within one second, do a sleep can make a big probability to get the latest data.

This program gives you a first impression, is likely to be children do not fly, no one should use it? And you might say, before the implementation of a direct statement to sleep when initiating a query, the user experience very friendly ah.

However, this idea can really solve the problem to some extent. In order to look more tricky children, we can put it another way.

Release of goods to the seller, for example, after the release of goods, with Ajax (Asynchronous JavaScript + XML, Asynchronous JavaScript and XML) content directly to client input as a "new product" is displayed on the page, but not really to do database queries .

In this way, the seller can, through this show, to confirm the success of the product has been released. Wait until the seller and then refresh the page to see the goods, in fact, has been for some time, also reached the purpose of sleep, and then will solve the problem of overdue reading.

In other words, this program does solve sleep problems reading expired in similar scenarios. But, strictly speaking, this program problems is inaccurate. This imprecision includes two meanings:

  1. If the query request would be 0.5 seconds to get the correct result from the library, and the like will be 1 second;
  2. If the delay is more than one second, there will still expire read.

See here, you are not to have a "Are you kidding me" feeling, this improvement program can solve the problem at Ajax expired read a similar scene, but still how can one not fly children. Do not worry, and then I introduce you to some of the more accurate solution.

Analyzing standby program without delay

To ensure that the standby database without delay, there are usually three approaches.

Through the front of the first 25 articles, we know the value of the results show slave status in the seconds_behind_master parameters can be used to measure the length of the primary and delay time.

Therefore, a first method of ensuring that the primary and without delay , before every query request from the library, first determine whether seconds_behind_master is already equal to 0. If not equal to 0, it must wait until this parameter to 0 to execute queries.

seconds_behind_master is in seconds, if you think the accuracy is not enough, also compared the site and method may be employed to ensure GTID standby without delay, that is, the second and the third method we will say next.

3, the results show slave status is a partial screenshot.


                                                    Figure 3 show slave status results 

Now, we are by this result, take a look at the specifics of how to ensure without delay by comparing the primary and backup sites and GTID.

The second method , comparison standby sites without delay to ensure:

  • Master_Log_File and Read_Master_Log_Pos, represents the latest site to read the main library;
  • Relay_Master_Log_File and Exec_Master_Log_Pos, represents the latest sites prepared by the library to perform.

If Master_Log_File and Relay_Master_Log_File, Read_Master_Log_Pos Exec_Master_Log_Pos and these two sets of values ​​are identical, it indicates that the received synchronization log has been completed.

A third method , a set of comparative GTID standby without delay to ensure that:

  • Auto_Position = 1, which indicates the relationship between the use of standby GTID protocol.
  • Retrieved_Gtid_Set, all logs are GTID received by the library's collection;
  • Executed_Gtid_Set, is prepared by the library collection has been performed all GTID completed.

If the same two sets, said library prepared logs have been received synchronization is complete.

Visible contrast site and Comparative GTID two methods, better than if 0 is more accurate determination seconds_behind_master.

Before executing the query request, to determine whether the method from the library synchronization is complete, compared to the sleep program, the accuracy is indeed improved a lot, but still did not reach the "precision" level. Why do you say?

We are now together under review, a transaction between the master and slave binlog library status:

  1. Main library complete execution, write the binlog, and back to the client;
  2. binlog is transmitted from the master to the standby database repository, received by the library;
  3. Completed in standby database to perform binlog.

We determined above standby without delay logic, a "log book library perform complete received." However, the analysis binlog state between the master and slave, as well as part of the log is easy to see, at the client has confirmed receipt of the submission, but not received by the library status logs.

Such a state is shown in Figure 4.


                                                        4 by the library have not received trx3 FIG.

At this time, the implementation of the completion of the three transactions trx1, trx2 and trx3 the main library, in which:

  1. trx1 and trx2 has spread from the library, and has completed execution;
  2. trx3 execution is complete at the main library, and has returned to the client, but has not spread to from the library.

If at this time you execute the query request from the database B, according to our logic above, from the library believed to have no synchronization delay, but still can not find the trx3. Strictly speaking, there was an expired read.

Well, the problem there is no way to solve it?

With semi-sync

To solve this problem, it is necessary to introduce semi-synchronous replication, which is semi-sync replication.

semi-sync made such a design:

  1. When the transaction is committed, the main library binlog sent from the library;
  2. After receiving binlog from the library, back to the main library a ack, he acknowledged receipt;
  3. After the main library received the ack, can be returned to the client "transaction completed" confirmation.

That is, if the semi-sync is enabled, it means that all transactions sent a confirmation to the client, both to ensure that the standby database has received this log.

In the first 25 articles of the comments area, and some students asked: If the main library down time, had a chance to send some binlog from a library, the system will not cause data loss?

The answer is, if you use an ordinary asynchronous replication mode, it may be lost, but the semi-sync can solve this problem.

Thus, semi-sync with the foregoing determination on site, it is possible to determine from the query request execution library, reading of date avoided.

However, semi-sync + site determination scheme, only a main one scene is established. In a multi-master from the scene, the main library just wait for ack from a library, began to return to the client confirmed. In this case, execute queries on the database, there are two cases:

  1. If the query is this fall in response to the ack from the library, read the latest data can be ensured;
  2. However, if the query falls from other libraries, they may have not received the latest log, problems arise expired reading.

In fact, the judgment program synchronizing site there is another potential problem, namely: if the business update of the peak of the main library or site collection GTID update soon, then the above two sites will be judged equivalent not been established, the situation from the library so they could not respond to the query request is likely to occur.

In fact, back to our original business logic, the When initiating a query request, we want to get accurate results, in fact, do not need to wait until the "standby complete sync."

Why do you say? We look at this timing diagram.

                                                          FIG 5 a standby delay duration transaction

As shown in FIG. 5, it is to wait for a site plan bad case. The dashed box in FIG standby database B, respectively, and binlog relaylog of transaction. It can be seen from FIG. 5 state 1 to state 4, the delay has been in a status of the transaction.

B has been prepared by the library to the state 4 and A are the main library there is a delay, if the above must wait until the program without delay to the query, select statement is not to be executed until the state 4.

But, in fact, the client is initiated after the update finished trx1 select statement, we just need to make sure trx1 has completed implementation of the select statement can be executed. That is, if the query is executed request in state 3, is expected to get the results.

Here, we look summary, semi-sync with the standby program determines no delay, there are two problems:

  1. When a master multi-slaves, in the implementation of certain queries from the library there will be expired reading of the phenomenon;
  2. In the case of continuous delays, the problem of excessive waiting may occur.

And other main library site plan Next, I want to introduce you, we can solve these two problems.

And other main library site plan

To understand the main library and other sites program, and I need to introduce you to a command:

select master_pos_wait(file, pos[, timeout]);
复制代码

This command logic is as follows:

  1. It is carried out from the library;
  2. Pos parameter file and refer to the file name and location on the main library;
  3. Alternatively timeout, setting N represents a positive integer up to this function waits N seconds.

This command returns the normal result is a positive integer M, indicating that the command is executed from, to complete and file the application binlog position pos represented, how many transactions are executed.

Of course, in addition to the normal return a positive integer M, the command also returns some of this additional results, comprising:

  1. If during execution, prepared by the library synchronize threads exception occurs, NULL is returned;
  2. If the wait for more than N seconds, it returns -1;
  3. If the beginning of the implementation, we found that this position has already been performed, and 0 is returned.

For the first implementation in Figure 5 trx1, then perform a logical query request, can be found to ensure that the correct data, we can use this logic:

  1. After the update is complete trx1 transaction, executed immediately show master status to get the current main library to perform the File and Position;
  2. Selected execute a query from the library;
  3. In execution select master_pos_wait (File, Position, 1) from the library;
  4. If the value is> = 0 of positive integers, then execute this query from the library;
  5. Otherwise, the main library to execute a query.

I have drawn above this process.


                                                     FIG Scheme 6 master_pos_wait

Here we assume that most of this select query from the library to wait on one second. So, if a master_pos_wait returns an integer greater than 1 second equal to 0 and ensuring the implementation of the query results from the database must contain the data trx1.

Step 5 execute a query to the main library, it is a common degradation mechanisms such programs. Because the delay time from the library uncontrollable, can not wait indefinitely, so if you wait timeout, you should give up, and then to the main library to investigate.

You might say, if all of the libraries are delayed more than one second, that the pressure is not on the inquiry have come to the main library yet? Indeed it is.

However, according to our reading of the requirements set does not permit expired, only two options, one is to give up overtime, one is go to the main database queries. Specifically how to select, you need to develop the students do a good job limiting business strategy.

GTID program

If your database opens GTID mode, there are corresponding schemes of waiting GTID.

In MySQL also provides a similar command:

 select wait_for_executed_gtid_set(gtid_set, 1);
复制代码

The logic of this command is:

  1. Wait until the execution of this transaction is included in the library incoming gtid_set, return 0;
  2. Timeout returns 1.

In front of the program and other sites. After we finished the implementation of the transaction, but also take the initiative to go to the main library to perform show master status. The MySQL 5.7.6 version, allowing the class after performing the update transaction, the GTID this transaction back to the client, such as GTID such programs can reduce a query.

At this time, such as the implementation process GTID then becomes:

  1. After trx1 transaction update is complete, return package direct access from this transaction GTID, referred to as gtid1;
  2. Selected execute a query from the library;
  3. In the execution select wait_for_executed_gtid_set (gtid1, 1) from the library;
  4. If the return value is 0, then execute a query from the library in this;
  5. Otherwise, the main library to execute a query.

With the main library and other sites in the same program, whether directly to the main database query wait times out, the students need to do business development limiting consideration.

I took this picture out of the process.


                                                 FIG Scheme 7 wait_for_executed_gtid_set 

After the above first step, trx1 transaction update is complete, get this GTID transactions directly from the return package. The question is, how can let MySQL after the implementation of the transaction, return the package to bring GTID it?

You only need to set the parameters session_track_gtids OWN_GTID, and then parse out the value from the return package to GTID via API interface mysql_session_track_get_first.

In the first article column, I introduced mysql_reset_connection when the comments area students have a message asking how such interfaces should be used.

Here I will answer this question. In fact, MySQL does not provide such an interface SQL usage, is available to program API (https://dev.mysql.com/doc/refman/5.7/en/c-api-functions.html)

For example, in order for the client in the transaction commits, returned GITD can be displayed on the client side, I made a point to modify MySQL client code, as follows:


                                       Figure 8 shows the code update transactions GTID--

In this way, you can see the complete statement execution, showing the value of GITD.


                                        Figure 9 shows the effect of the update transaction GTID--

Of course, this is just one example. You want to use this program when mysql_session_track_get_first or should call this function in your client code.

summary

In today's article, I introduced a multi-master from doing separate read and write, the reason may be encountered expired reading, as well as several programs to deal with you.

These types of programs, the program appears to be doing some compromise, some programs do not look so fly children, but there are practical application scenarios, you need to choose based on business needs.

Even the last wait sites and wait GTID these two programs, although it seems more reliable child, but there is still need to weigh the situation. If all of the libraries are delayed, then the request will fall on all of the main library, this time will not be due to the sudden increase in pressure, the main library and hanging out?

In fact, in practical applications, these solutions can be mixed use.

For example, the first client to do classification request, which requests to distinguish between acceptable expired read, and which expired read request is totally unacceptable; and, for unacceptable expired read the statement, re-use and other programs such as GTID or sites.

But having said that, in essence expired reading is a result of a write once read many. In practice, there may be no need to wait on the other horizontally scalable database program, but it often is sacrificed in exchange for write performance, which is required to take a trade-off in performance read and write performance.

Finally, I leave you a question now.

Assuming that your system uses the last program we introduced in this paper, that is, such as GTID program, and now you want to do on a large table DDL main library, what might happen? To avoid this situation, how would you do it?

You can put your analysis and program design to write in the comments section, I will discuss this issue with you in the next article. Thank you for listening, you are welcome to send this share to more friends to read together.

On the issue of time

Problem of left you are in GTID mode, if a new one from the library connected to the main library, but need binlog gone, how to do?

@ A, students who gave a very detailed analysis, I took his answer slightly modified paste over.

  1. If the service allows master-slave inconsistencies, you can first perform in the main gallery show global variables like 'gtid_purged', get GTID collection main library has been deleted, the assumption is gtid_purged1; then the first execution reset master from the library, and then execute set global gtid_purged = 'gtid_purged1'; last execution start slave, will start the synchronization from the master library existing binlog. binlog missing that part, on data from the library there might be a lost cause from the main inconsistency.
  2. If you need a consistent master data from it, is best done by re-build from the library.
  3. If there are other retains the full amount of the binlog from the library, you can put a new library from the first received the full amount binlog retained from the library, after the catch logs, if necessary, draw a line back to the main library.
  4. If there are circumstances backup binlog, you can apply the missing from the library binlog, and then perform start slave.


Reproduced in: https: //juejin.im/post/5d05b896f265da1bbf691ba7

Guess you like

Origin blog.csdn.net/weixin_33712881/article/details/93183413