[MDEV-23545] Add Trigger-View capability Created: 2020-08-23 Updated: 2020-08-25 |
|
| Status: | Open |
| Project: | MariaDB Server |
| Component/s: | None |
| Fix Version/s: | None |
| Type: | Task | Priority: | Minor |
| Reporter: | Todd Hubers | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Issue Links: |
|
||||||||
| Description |
|
This would be somewhat comparable to Oracle Database Continuous Query Notification, SQL Server waitfor/receive, and Postgresql Listen / Notify; but better. Instead of https://jira.mariadb.org/browse/MDEV-16590, this feature would provide a simpler and more developer-friendly SQL based API to be notified quickly when new records become available. The experience may be like the following
Where an external process could use a client driver like this
I am not familiar with the source code for MySQL. Perhaps implementation could effectively be like a long-poll or cursor. I'm not sure if the internal mechanisms would require a complete overhaul though. At the highest database driver level, the client library is waiting for another network packet with more data for that resultset, so there should be no significant resources used up, except potentially for the resultset context on the serverside. System-defined Views would be available per table, or may be defined using new keywords like `WITH Trigger(Sales, Insert)`. Such Views may be joined to other tables, but MUST BE the first FROM-SOURCE of the View, and the only Trigger-View. Learning from SQL Server, perhaps these should be Queue-Views, but simpler, where triggers are enqueuing to active Views at the time; not requiring a broker. |
| Comments |
| Comment by Daniel Black [ 2020-08-24 ] | ||||||||||||||||||||||||||||||||||||
|
Maybe you could use [master_gtid_wait https://mariadb.com/kb/en/master_gtid_wait/] as the ReadAsync mechanism and a specific domain-id in the gtid to indicate the queue you want. (disclaimer untested) | ||||||||||||||||||||||||||||||||||||
| Comment by Todd Hubers [ 2020-08-24 ] | ||||||||||||||||||||||||||||||||||||
|
Another approach: select * from StreamView_Sales_Inserted where ID > cutIn and SaleAmount > 10000 wait 1; – new keyword, that requires at least 1 record before the statement completes. internally. (limit could also be used) This statement is looped, and the cutIn variable is increased each time from the last ID that was returned. In C#, it would block the longest at ExecuteReaderAsync. But ideally, the 'wait' keyword would not be necessary. Ideally, the callback registration occurs for this special VIEW first, then the table is queried according to the filter clauses, then the rows are returned and the read-lock is relinquished, then it waits and notes the max(ID), then when it's signalled it gets a read-lock and applies the updated max(ID) filter, returns new records, and the cycle continues. Max(ID) isn't the only way though. If there is an internal mechanism, perhaps the [NEW] table of the insert trigger is used instead. | ||||||||||||||||||||||||||||||||||||
| Comment by Daniel Black [ 2020-08-24 ] | ||||||||||||||||||||||||||||||||||||
|
Or the client becomes a replication client filtered to the table. I'm still of the general option that I stated in the linked MDEV 2 years ago that message queue applications are mature and there's no need for a SQL server to undergo large changes internally to forfil a function that alternate message queue products have reached a significant maturity with, have a better application interface, and have more options and monitoring tools associated with them. | ||||||||||||||||||||||||||||||||||||
| Comment by Todd Hubers [ 2020-08-25 ] | ||||||||||||||||||||||||||||||||||||
|
Thanks Daniel. I'm not sure how to @mention in Jira. Disclaimer: I haven't read deeply about GTIDs yet I don't foresee a replication client approach being the right solution for what I am looking for. If there are 1000 endpoints I assume that 1000 read replica streams would be necessary, each filtering to a subset of target-table events. This would not be scalable. Mechanics Progress Instead, there might be the following implementation:
Here is a user implementation in a pseudocoded stored procedure for streaming an insert view:
In the stored procedure version above, the client will receive multiple result-sets, and may receive duplicate records in some overlap circumstances. This can be avoided by using a temp table and getting the Max(ChangeSequenceID) before selecting those records onwards to the caller. If TableWait is implemented in the database client protocol, then the server-side would only need to remember which connection references to signal and wouldn't need to keep any stored procedure state (activity registration), and so this could be implemented remotely (distributed):
A system-implementation of a WaitView would benefit from async coding, conventional system-level use of the SequenceID, and the ability to present it as a "VIEW" and not a Stored Procedure, because then such a WaitView can be joined to other tables. (The client-driver might participate when "SET WaitView=REMOTE" where the client driver retains the context to continue the WaitView execution and waits for the network packet before sending the necessary command to continue the WaitView.) Merit RE: "message queue applications are mature": I strongly believe that all databases need a trigger event system that propagates through the established database connection. Even better if there are several means. One could be Publish/Notify; the other could resemble what I am proposing on this task. I proceed with the following understanding:
I am happy to debate these, and I am happy to be proven wrong, but you may already agree with all/some of the assertions. However, I prefer to keep these as good approximations that can be qualified in time. I think a proposal document is necessary:
Then with all of the pertinent information in one place, I trust a discussion may proceed of "when" rather than "whether" something like this would be built for MySQL. |