gh-ost icon indicating copy to clipboard operation
gh-ost copied to clipboard

optimize migrator's executeWriteFuncs

Open debug-LiXiwen opened this issue 2 years ago • 5 comments

A Pull Request should be associated with an Issue.

Description

  • Migrator's executeWriteFuncs will have a infinite loop when applyEventsQueue and copyRowsQueue is empty.
  • So I Optimize the priority logic to avoid the infinite loop

debug-LiXiwen avatar May 15 '22 12:05 debug-LiXiwen

@debug-LiXiwen thanks for the PR changes, it is passing CI now 👍

Now that the code looks good, I'm curious if you could explain what situations this optimizes?

If I understand correctly, this is the scenario this optimizes:

  1. case eventStruct := <-this.applyEventsQueue() returns empty (no events)
  2. Immediately after, events are added to the applier queue that were not seen by case in the last step
  3. The select moves on to case copyRowsFunc := <-this.copyRowsQueue(), which is NOT empty
  4. The new func this.drainApplierEventQueue() drains the events that appeared at step 2 (above)
    • On master today, the for loop would need to iterate again to catch the new applier events

Did I get this right and are there more scenarios?

The "window" for these events to appear above is extremely small. How likely is it that this scenario happens? Shouldn't the applier queue be empty by the time this.drainApplierEventQueue() is called? 🤔

timvaillancourt avatar Aug 21 '22 23:08 timvaillancourt

  1. When the copyRowsQueue is not ready, you don't need to sleep manually, the select of the go language will be handled automatically
  2. When the copyRowsQueue is ready, logically analyze the new way of processing to achieve better prioritization, but I did not verify the effect in the actual scene

debug-LiXiwen avatar Aug 22 '22 02:08 debug-LiXiwen

  1. you don't need to sleep manually, the select of the go language will be handled automatically

That's a good point, the time.Sleep() is a bit inefficient. Thanks for explaining 👍

timvaillancourt avatar Aug 23 '22 22:08 timvaillancourt

Thanks for your contribution @debug-LiXiwen! 🙇

  1. When the copyRowsQueue is not ready, you don't need to sleep manually, the select of the go language will be handled automatically

I think relying on select to wait instead of using time.Sleep is a good idea as it makes the code easier to read. I don't think the performance difference will be significant, but I like that it makes the code flow better.

  1. When the copyRowsQueue is ready, logically analyze the new way of processing to achieve better prioritization, but I did not verify the effect in the actual scene

I think drainApplierEventQueue() is unnecessary and we should remove it. I understand the reason for this optimisation, but the benefit will be very small and it makes the code more complicated than necessary. I prefer that we keep the code as simple as possible, and only optimise when there's a demonstrated need.

dm-2 avatar Sep 06 '22 11:09 dm-2

I don't think the performance difference will be significant, but I like that it makes the code flow better.

Agreed, I think it's very unlikely this would improve performance for most workloads

I think drainApplierEventQueue() is unnecessary and we should remove it

I would be on board with this 👍. It's is incredibly unlikely there are new events to apply immediately after the select already checked the apply queue

timvaillancourt avatar Sep 06 '22 14:09 timvaillancourt