áááŒá¬áá±ážáá®á áá»áœááºá¯ááºááá¯á·ááẠáá±áá¬ááœááºáá»á¬ážááœáẠtuples áá»á¬ážááᯠááá·áºááŸááºážáá±ážáá¯ááºááá·áº ááŒá¿áá¬ááŸáá·áº áááºááá¯ááºáá²á·ááááºá
áá»áœááºá¯ááºááá¯á·á¡ááœáẠááá°áá¬áá±á¬ááºážáá
áºáá¯ááŸá¬ tarantool áá¯áá±á«áºáá±á¬ áá±á¬áºáá»á°ážááŒá
áºáááºá
áá±á«áºááŒáá»ááº
tarantool á¡ááœáẠá
á¬ááœááºá
á¬áááºážááẠá¡ááœááºáá±á¬ááºážááœááºáááºá
á¡áá±ážááá± á ááŒá®áž áá¯ááºáá¬ážáá²á· áááºáááºážáá¯ááºáá¯á¶ážááœá¬ážáá²á· áá±á¬áºáá»á°ážááᯠá¡ááŒááºááá± áááºááá¯áá¯á¶á á¶áá²á· ááŒáá·áºááŒáá·áºáá¡á±á¬ááºá
fiber = require('fiber')
net_box = require('net.box')
box.cfg{listen = 3300}
box.schema.func.create('libcapped-expirationd.start', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.start')
box.schema.func.create('libcapped-expirationd.kill', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.kill')
box.schema.space.create('tester')
box.space.tester:create_index('primary', {unique = true, parts = {1, 'unsigned'}})
capped_connection = net_box:new(3300)
ááá¯ážááŸááºážáááºá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠáá»áœááºá¯ááºááá¯á·á libcapped-expirationd.so á á¬ááŒáá·áºááá¯ááºáááºááŸááᬠáááºážááœáŸááºááœáẠtarantool ááá¯ááœáá·áºááá¯ááºáá«á áá¯ááºáá±á¬ááºáá»ááºááŸá áºáá¯ááᯠáá áºáá»á áºááá¯ááºá០áááºááá¯á·áááº- á áááºááŒááºážááŸáá·áº áááºáá áºááŒááºážá áááá¡ááá·áºááŸá¬ box.schema.func.create ááŸáá·áº box.schema.user.grant ááᯠá¡áá¯á¶ážááŒá¯á Lua á០á€áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠáááŸáááá¯ááºá á±áááºááŒá áºáááºá ááá¯á·áá±á¬áẠtuples ááœáẠá¡ááœááºáá¯á¶ážáá¯áá¬áá«áááºááá·áº áá±áá¬áá áºáá¯ááᯠáááºáá®ážáá«- ááááá áºáá¯ááẠáá°ážááŒá¬ážáá±á¬áááºááŸááºááŸá¯ááŒá áºááŒá®áž áá¯áááááŸá¬ á¡á®ážáá±ážááºááŒá áºááŒá®áž ááááááŸá¬ tuple ááááºáááºážááŒá áºáááºá áá»áœááºá¯ááºááá¯á·ááẠáááá¡ááœááºáááááºááœáẠáá áºáááºá¡ááœáŸááºážáá áºáá¯ááᯠáááºáá±á¬ááºááŒá®áž áááºážááᯠáá°ááááºážáá¯áá±á«áºáááºá ááá¯á·áá±á¬áẠáá»áœááºá¯ááºááá¯á·ááẠáá»áœááºá¯ááºááá¯á·á áá°áá á¬ááŒáá·áºááá¯ááºááá¯á· áá»áááºáááºááŸá¯á¡áá¬ááá¹áá¯ááᯠááá°áá«áááºá
ááŒáá¯áááºááŒááºáááºááŸá¯á¡ááŒá®ážááœááºá á áááºááá·áºáá¯ááºáá±á¬ááºáá»ááºááᯠáá¯ááºáá±á¬ááºáá«á
capped_connection:call('libcapped-expirationd.start', {'non-indexed', box.space.tester.id, box.space.tester.index.primary, box.space.tester.index.primary, 3, 1024, 3600})
á€á¥ááá¬ááẠLua ááœááºáá±ážáá¬ážááá·áº áááºáááºážáá¯ááºáá¯á¶ážáá±áá±á¬ module ááŸáá·áº á¡ááá¡áá»áá°áá®áá±á¬á áááºááºáááºáá±á ááºá¡ááœááºáž á¡áá¯ááºáá¯ááºáááºááŒá áºáááºá start function á¡ááœáẠááááá¯á¶áž argument ááẠtask á áá°ážááŒá¬ážáá±á¬ á¡áááºááŒá áºáá«áááºá áá¯áááááŸá¬ space identifier ááŒá áºáááºá ááááááẠtuple áá»á¬ážááá¯áá»ááºááá·áºáá°ážááŒá¬ážáá±á¬á¡ááœáŸááºážáá áºáá¯ááŒá áºáááºá á áá¯áá¹áááẠtuples áá»á¬ážááá¯ááŒááºáááºážááá·áºá¡ááœáŸááºážááááºážááŒá áºáááºá ááá¹á áááẠáá áºáááºáá¬ááŸáá·áºá¡áá° tuple á¡ááœááºááá¶áá«ááºááŒá áºááẠ(áá¶áá«ááºááẠ1 ááŸá áááºáááºá 0 ááá¯ááºáá«á!) ááá¹ááááŸáá·áº ááá¹ááááá¯á·ááẠá áááºáááºááŒááºáž áááºáááºáá»á¬ážááŒá áºáááºá 1024 ááẠááœá±áá±ážááœá±áá°áá áºáá¯áááºážááœáẠááŒáá·áºááŸá¯ááá¯ááºááá·áº tuple á¡áá±á¡ááœáẠá¡áá»á¬ážáá¯á¶ážááŒá áºáááºá 3600 â á áá¹ááá·áºááá¯ááºážá¡ááœááºáž á áááºáááºáá»áááºá¡ááŒáá·áºá
á¥ááá¬ááẠáá°ážáá°ááŒááºážááŸáá·áº áá»ááºááŒááºážá¡ááœáẠáá°áá®áá±á¬á¡ááœáŸááºážááᯠá¡áá¯á¶ážááŒá¯ááŒá±á¬ááºáž áááááŒá¯áá«á áááºážááẠáá áºáááºá¡ááœáŸááºážááŒá áºáá«áá áá±ážáááºáá±á¬áá±á¬á·á០ááá¯ááŒá®ážááá·áºá¡áá ááŒááºááœá¬ážááŒááºážááᯠáá¯ááºáá±á¬ááºáááºá á¥ááá¬á¡á¬ážááŒáá·áº hash index á¡áá»áá¯á·ááŸááá«áá á ááºážáááºážá¡ááá¯ááºážá áá»áááºážá¡á á®á¡á á¥áºááŒáá·áº ááŒááºáááºážááŒááºážááᯠáá¯ááºáá±á¬ááºáááºá á¡á¬áá¬á tuple á¡á¬ážáá¯á¶ážááᯠá áááºááºáá áºáá¯ááœáẠá áááºááºáááºáááºá
áá áºáááºáᬠá áá¹ááá·áº 60 ááŒáá·áº á¡á¬áá¬ááá²ááá¯á· tuple áá»á¬ážá áœá¬ááᯠááá·áºááœááºážááŒáá«á áá¯á·á
box.space.tester:insert{0, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{1, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{2, '[email protected]', math.floor(fiber.time()) + 60}
ááá·áºááœááºážááŸá¯ á¡á±á¬ááºááŒááºááŒá±á¬ááºáž á á áºáá±ážááŒáá·áºááŒáá«á áá¯á·á
tarantool> box.space.tester.index.primary:select()
---
- - [0, '[email protected]', 1576418976]
- [1, '[email protected]', 1576418976]
- [2, '[email protected]', 1576418976]
...
60+ á áá¹ááá·áºá¡ááŒá¬ááœáẠááœá±ážáá»ááºááŸá¯ááᯠááŒááºáá¯ááºááŒáá·áºáá¡á±á¬áẠ(ááá tuple áá¡á ááœáẠááá·áºááœááºážááŒááºážá¡á á០áá±ááœááºááŒááºáž) ááŸáá·áº capped áááºáááºážáá¯ááºáá¯á¶ážááœá¬ážáá±á¬ module ááẠáá¯ááºáá±á¬ááºááŒá®ážááŒá áºáááºááᯠááŒáá·áºááŒáá«á áá¯á·á
tarantool> box.space.tester.index.primary:select()
---
- []
...
áá¬áááºááᯠáááºááá¯ááºááŒáá¡á±á¬ááºá
capped_connection:call('libcapped-expirationd.kill', {'non-indexed'})
áá°ážáá°ááŒááºážá¡ááœáẠáá®ážááŒá¬ážá¡ááœáŸááºážááᯠá¡áá¯á¶ážááŒá¯ááá·áº áá¯áááá¥ááá¬ááᯠááŒáá·áºááŒáá«á áá¯á·á
fiber = require('fiber')
net_box = require('net.box')
box.cfg{listen = 3300}
box.schema.func.create('libcapped-expirationd.start', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.start')
box.schema.func.create('libcapped-expirationd.kill', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.kill')
box.schema.space.create('tester')
box.space.tester:create_index('primary', {unique = true, parts = {1, 'unsigned'}})
box.space.tester:create_index('exp', {unique = false, parts = {3, 'unsigned'}})
capped_connection = net_box:new(3300)
á€áá±áá¬ááœáẠá¡áá¬á¡á¬ážáá¯á¶ážááẠááŒáœááºážáá»ááºá¡áááºážáááºááŒáá·áº áááá¥ááá¬ááœáẠáá°áá®áá«áááºá áá»áœááºá¯ááºááá¯á·ááẠááááá¡ááœááºáááááºááœáẠáá áºáááºá¡ááœáŸááºážáá áºáá¯ááᯠáááºáá±á¬ááºááŒá®áž exp áá¯áá±á«áºáááºá á€á¡ááœáŸááºážááẠáá°ááá¯áá±á«áºáá±á¬ á¡ááœáŸááºážááŸáá·áºááá°áá² áá°ážááŒá¬ážáá±ááẠáááá¯á¡ááºáá«á á¡áá°ážá¡ááŒá±á¬ááºážááᯠexp á¡ááœáŸááºážááŒáá·áº áá¯ááºáá±á¬ááºáááºááŒá áºááŒá®ážá á¡áááá¡á¬ážááŒáá·áº áá»ááºááŒááºážááᯠáá¯ááºáá±á¬ááºáááºááŒá áºáááºá ááááºá ááŸá áºáá¯á áá¯á¶ážááᯠáá°áá¡ááœáŸááºážááᯠá¡áá¯á¶ážááŒá¯á áá¯ááºáá±á¬ááºáá²á·ááŒá±á¬ááºáž áá»áœááºá¯ááºááá¯á· áááááááááºá
ááŒáá¯áááºááŒááºáááºááŸá¯á¡ááŒá®ážááœááºá áá»áœááºá¯ááºááá¯á·ááẠá¡ááŒá±á¬ááºážááŒáá»ááºá¡áá áºáá»á¬ážááŒáá·áº á áááºááá·áºáá¯ááºáá±á¬ááºáá»ááºááᯠáá¯ááºáá±á¬ááºáááº-
capped_connection:call('libcapped-expirationd.start', {'indexed', box.space.tester.id, box.space.tester.index.primary, box.space.tester.index.exp, 3, 1024, 3600})
áá áºáááºáᬠá áá¹ááá·áº 60 ááŒáá·áº á¡á¬áá¬ááá²ááá¯á· tuple áá»á¬ážá áœá¬ááᯠáááºááá·áºááŒáá«á áá¯á·á
box.space.tester:insert{0, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{1, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{2, '[email protected]', math.floor(fiber.time()) + 60}
á áá¹ááá·áº 30 ááŒá¬ááŒá®ážáá±á¬ááºá á¥ááá¬á¡á¬ážááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠáá±á¬ááºááẠtuples á¡áááºážáááºááᯠáááºááá·áºáá«áááºá
box.space.tester:insert{3, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{4, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{5, '[email protected]', math.floor(fiber.time()) + 60}
ááá·áºááœááºážááŸá¯ á¡á±á¬ááºááŒááºááŒá±á¬ááºáž á á áºáá±ážááŒáá·áºááŒáá«á áá¯á·á
tarantool> box.space.tester.index.primary:select()
---
- - [0, '[email protected]', 1576421257]
- [1, '[email protected]', 1576421257]
- [2, '[email protected]', 1576421257]
- [3, '[email protected]', 1576421287]
- [4, '[email protected]', 1576421287]
- [5, '[email protected]', 1576421287]
...
60+ á áá¹ááá·áºá¡ááŒá¬ááœáẠááœá±ážáá»ááºááŸá¯ááᯠááŒááºáá¯ááºááŒáá·áºáá¡á±á¬áẠ(ááá tuple áá¡á ááœáẠááá·áºááœááºážááŒááºážá¡á á០áá±ááœááºááŒááºáž) ááŸáá·áº capped áááºáááºážáá¯ááºáá¯á¶ážááœá¬ážáá±á¬ module ááẠáá¯ááºáá±á¬ááºááŒá®ážááŒá áºáááºááᯠááŒáá·áºááŒáá«á áá¯á·á
tarantool> box.space.tester.index.primary:select()
---
- - [3, '[email protected]', 1576421287]
- [4, '[email protected]', 1576421287]
- [5, '[email protected]', 1576421287]
...
á¡áááºááŸááºááẠá áá¹ááá·áº 30 ááá·áºáᬠáá»ááºááŸááá±á¬á·ááá·áº á¡á¬áá¬ááá²ááœáẠáá»á°ááá®á¡áá»áá¯á· áá»ááºáá±áá±ážáááºá ááá¯á·á¡ááŒááºá ID 2 ááŸááá±á¬ tuple á០1576421257 ááŸáá·áº 3 ID ááŸááá±á¬ tuple ááŸáá·áº áá áºáááºáᬠ1576421287 ááá¯á· ááœá±á·áá»á¬ážááá·áºá¡áá« á áááºááºáááºááá·áºááœá¬ážáá«áááºá 1576421287 ááá¯á·ááá¯áẠáá áºáááºáᬠXNUMX ááá¯á·ááá¯áẠááá¯á·áááºááá¯áá±á¬ tuple áá»á¬ážááᯠá áááºááºááááºááá¯ááºáá«á exp á¡ááœáŸááºážáá®ážáá»á¬ážá áá«á á¡á ááŸá¬ ááá¯áá»ááºáá²á· á á¯áá±á¬ááºážááœá±áá«á
áá¬áááºááᯠáááºááá¯ááºááŒáá¡á±á¬ááºá
capped_connection:call('libcapped-expirationd.kill', {'indexed'})
á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯
ááá±á¬áá»ááºáá
áºáá¯á á¡ááºá¹áá«áááºáá»á¬ážá¡á¬ážáá¯á¶ážááᯠááŒá±á¬ááŒááẠá¡áá±á¬ááºážáá¯á¶ážáááºážáááºážááŸá¬ áááºážááá°áááºážáááºážááŒá
áºááŒá
áºáááºá
á áááºáááºážáááºážááá¯á· áá»áœááºá¯ááºááá¯á·áá±ážááá¯á·áá±á¬ á¡ááŒá±á¬ááºážááŒáá»ááºáá»á¬ážááᯠexpirationd_task áá¯áá±á«áºáá±á¬ ááœá²á·á ááºážáá¯á¶ááœáẠááááºážáááºážáá¬ážáááºá
struct expirationd_task
{
char name[256];
uint32_t space_id;
uint32_t rm_index_id;
uint32_t it_index_id;
uint32_t it_index_type;
uint32_t field_no;
uint32_t scan_size;
uint32_t scan_time;
};
name attribute ááẠá¡áá¯ááºáá¡áááºááŒá áºáááºá space_id áááºááœáŸááºážáá»ááºááẠspace identifier ááŒá áºáááºá rm_index_id áááºááœáŸááºážáá»ááºááẠtuples áá»á¬ážááᯠáá»ááºáá áºááá·áº áá®ážááŒá¬ážá¡ááœáŸááºážááááºážá á¡áá±á¬ááºá¡áá¬ážááŒá áºáááºá it_index_id áááºááœáŸááºážáá»ááºááẠtuples ááá¯ááŒááºááœá¬ážááá·áº á¡ááœáŸááºážááááºážá identifier ááŒá áºáááºá it_index_type áááºááœáŸááºážáá»ááºááẠtuples ááá¯ááŒááºááœá¬ážááá·áº á¡ááœáŸááºážá¡áá»áá¯ážá¡á á¬ážááŒá áºáááºá filed_no áááºááœáŸááºážáá»ááºááẠáá áºáááºáá¬ááŸáá·áºá¡áá° tuple á¡ááœááºá áá¶áá«ááºááŒá áºáááºá scan_size áááºááœáŸááºážáá»ááºááẠááœá±áá±ážááœá±áá°áá áºáá¯ááœáẠá áááºááºáááºáá¬ážáá±á¬ tuples á¡áá»á¬ážáá¯á¶ážá¡áá±á¡ááœááºááŒá áºáááºá scan_time áááºááœáŸááºážáá»ááºááẠá áá¹ááá·áºááá¯ááºážá¡ááœááºáž á¡ááŒáá·áºá¡á á áááºáááºáá»áááºááŒá áºáááºá
á¡ááŒááºážá¡áá¯á¶áá»á¬ážááᯠááá¯ááºážááŒá¬ážá
ááºážá
á¬ážáááºááá¯ááºáá«á á
á¬ááŒáá·áºááá¯ááºááẠááá·áºá¡á¬áž áá°áá®áá±ážááá·áº áá®áááááŸááá±á¬áºáááºáž ááá¯ážááŸááºážáá±á¬á¡áá¯ááºááŒá
áºáááºá
áá»áœááºá¯ááºááá¯á·ááẠááœá²ááŒááºážá áááºááŒá¬áááºá¡ááœáẠá¡áá¯á¶ážááŒá¯ááá·áº áá¯ááºáá±á¬ááºáá»ááºá¡á¬ážáá¯á¶ážá ááŸá±á·ááŒá±ážáá¯á¶á á¶áá»á¬ážááᯠá á¬áááºážááŒá¯á á¯áá¬ážáá«áááºá
bool expirationd_parse_name(struct expirationd_task *task, const char **pos);
bool expirationd_parse_space_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index_unique(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index_type(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index(struct expirationd_task *task, const char **pos);
bool expirationd_parse_field_no(struct expirationd_task *task, const char **pos);
bool expirationd_parse_scan_size(struct expirationd_task *task, const char **pos);
bool expirationd_parse_scan_time(struct expirationd_task *task, const char **pos);
á¡áᯠá¡áá±ážááŒá®ážáá¯á¶ážá¡áᬠ- space ááá¯áá»á±á¬áºááŒááºááŒá®áž tuples ááœá±ááᯠáá»ááºááŒááºážáá²á· áá¯áá¹ááááᯠáááºááŒáá·áºáá¡á±á¬ááºá scan_size áááºáááŒá®ážáá±á¬ tuple áá¯á¶ážáá áºáá¯á á®ááᯠá¡áá±á¬ááºážá¡áááºáá áºáá¯áááºážá¡á±á¬ááºááœáẠá áááºáááºááŒá®áž ááŒá¯ááŒááºááœááºážáá¶áá¬ážáááºá á¡á±á¬ááºááŒááºáá«áá á€ááœá±áá±ážááœá±áá°ááᯠáááááŒá¯áá¬ážááŒá®ážá á¡ááŸá¬ážá¡ááœááºážááŒá áºáá«áá áááºážááᯠááŒááºáááºáá¯ááºááááºážáááºááŒá áºáááºá expirationd_iterate áá¯ááºáá±á¬ááºáá»ááºá¡ááœáẠáá±á¬ááºáá¯á¶ážá¡ááŒááºážá¡áá¯á¶ááẠá áááºáááºá á áºáá±ážááŒááºáž á áááºááẠááá¯á·ááá¯áẠáááºáááºáá¯ááºáá±á¬ááºááá·áº iterator á¡á¬áž ááœáŸááºááŒáá»ááºááŒá áºáááºá á¡ááŸá¬ážá¡ááœááºážáá áºáá¯ááŒá áºááœá¬ážááŒááºážá áá±áá¬ááœááºáá¯ááºááœá¬ážáááºá¡áá ááá¯á·ááá¯áẠáá¯ááºáááºážá ááºááá¯ááŒáá¯áááºáááºááá·áºáááºáááŒá áºááá¯ááºááá»ááºáž á€áááºáááºáááááá¬ááᯠá¡ááœááºážááá¯ááºážá¡ááœááºáž ááá¯ážáá¬ážáááºá áá¯ááºáá±á¬ááºáá»áẠexpirationd_expired ááẠtuple áá áºáá¯á áááºáááºážááᯠá á áºáá±ážáááºá expirationd_delete ááẠtuple áá áºáá¯ááᯠáá»ááºáááºá expirationd_breakable checks ááẠáá»áœááºá¯ááºááá¯á· ááŸá±á·áááºááẠááá¯á¡ááºááŒááºáž ááŸááááŸá á á áºáá±ážáááºá
Expirationd_iterate áá¯ááºáá±á¬ááºáá»ááºáá¯ááº-
static bool
expirationd_iterate(struct expirationd_task *task, box_iterator_t **iterp)
{
box_iterator_t *iter = *iterp;
box_txn_begin();
for (uint32_t i = 0; i < task->scan_size; ++i) {
box_tuple_t *tuple = NULL;
if (box_iterator_next(iter, &tuple) < 0) {
box_iterator_free(iter);
*iterp = NULL;
box_txn_rollback();
return false;
}
if (!tuple) {
box_iterator_free(iter);
*iterp = NULL;
box_txn_commit();
return true;
}
if (expirationd_expired(task, tuple))
expirationd_delete(task, tuple);
else if (expirationd_breakable(task))
break;
}
box_txn_commit();
return true;
}
áá¯ááºáá±á¬ááºáá»ááºáá¯áẠáááºáááºážáá¯ááºáá¯á¶ážáááº_áááºáááºážáá¯ááºááœá¬ážáááº-
static bool
expirationd_expired(struct expirationd_task *task, box_tuple_t *tuple)
{
const char *buf = box_tuple_field(tuple, task->field_no - 1);
if (!buf || mp_typeof(*buf) != MP_UINT)
return false;
uint64_t val = mp_decode_uint(&buf);
if (val > fiber_time64() / 1000000)
return false;
return true;
}
Expirationd_delete áá¯ááºáá±á¬ááºáá»ááºáá¯ááº-
static void
expirationd_delete(struct expirationd_task *task, box_tuple_t *tuple)
{
uint32_t len;
const char *str = box_tuple_extract_key(tuple, task->space_id, task->rm_index_id, &len);
box_delete(task->space_id, task->rm_index_id, str, str + len, NULL);
}
Expirationd_breakable function code-
static bool
expirationd_breakable(struct expirationd_task *task)
{
return task->it_index_id != task->rm_index_id && task->it_index_type == ITER_GT;
}
ááŒáŸá±á¬áá»ááŸá¬
source code ááᯠááŸá¬ ááŒáá·áºááŸá¯ááá¯ááºáá«áááºá
source: www.habr.com