From 29dcaf3a788bbc472b0e3e89d799ca7da25bf209 Mon Sep 17 00:00:00 2001 From: jaybeepee Date: Tue, 8 Mar 2016 11:03:15 +0200 Subject: [PATCH] modules/ims_usrloc_scscf: improved mysql efficiency - added transaction instead of autocomitting each statement - changed query to more efficient join for many-to-many mapping deletion --- modules/ims_usrloc_scscf/impurecord.c | 46 +++++++++++++++++++++++++++ modules/ims_usrloc_scscf/usrloc_db.c | 4 +-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/modules/ims_usrloc_scscf/impurecord.c b/modules/ims_usrloc_scscf/impurecord.c index b8f0b93c960..9dd82ed974b 100644 --- a/modules/ims_usrloc_scscf/impurecord.c +++ b/modules/ims_usrloc_scscf/impurecord.c @@ -323,6 +323,28 @@ void mem_delete_ucontact(ucontact_t* _c) { mem_remove_ucontact(_c); free_ucontact(_c); } + +static str autocommit_off = str_init("SET AUTOCOMMIT=0"); +static str fail_isolation_level = str_init("SET TRANSACTION ISOLATION LEVEL READ COMMITTED"); +static str start_transaction = str_init("START TRANSACTION"); +static str commit = str_init("COMMIT"); +static str rollback = str_init("ROLLBACK"); +static str autocommit_on = str_init("SET AUTOCOMMIT=1"); + +static inline void start_dbtransaction() { + if (ul_dbf.raw_query(ul_dbh, &autocommit_off, NULL) < 0) { + LM_ERR("could not " + "set autocommit off!\n"); + } + if (ul_dbf.raw_query(ul_dbh, &fail_isolation_level, NULL) < 0) { + LM_ERR("could not " + "set transaction isolation level!\n"); + } + if (ul_dbf.raw_query(ul_dbh, &start_transaction, NULL) < 0) { + LM_ERR("could not " + "start transaction!\n"); + } +} /*! * \brief Expires timer for NO_DB db_mode * @@ -338,6 +360,7 @@ static inline void process_impurecord(impurecord_t* _r) { udomain_t* _d; reg_subscriber *s; subs_t* sub_dialog; + int dbwork = 0; get_act_time(); @@ -347,6 +370,10 @@ static inline void process_impurecord(impurecord_t* _r) { if (!valid_subscriber(s, act_time)) { LM_DBG("DBG:registrar_timer: Subscriber with watcher_contact <%.*s> and presentity uri <%.*s> expired and removed.\n", s->watcher_contact.len, s->watcher_contact.s, s->presentity_uri.len, s->presentity_uri.s); + if (!dbwork) { + start_dbtransaction(); + dbwork = 1; + } delete_subscriber(_r, s); } else { LM_DBG("DBG:registrar_timer: Subscriber with watcher_contact <%.*s> and presentity uri <%.*s> is valid and expires in %d seconds.\n", @@ -420,6 +447,10 @@ static inline void process_impurecord(impurecord_t* _r) { LM_DBG("\t\texpiring contact %i: [%.*s] in slot [%d]\n", n, contacts_to_expire[n]->c.len, contacts_to_expire[n]->c.s, contacts_to_expire[n]->sl); sl = ptr->sl; lock_contact_slot_i(sl); + if (!dbwork) { + start_dbtransaction(); + dbwork=1; + } unlink_contact_from_impu(_r, ptr, 1, 0 /*implicit dereg of contact from IMPU*/); unlock_contact_slot_i(sl); } @@ -429,6 +460,10 @@ static inline void process_impurecord(impurecord_t* _r) { LM_DBG("no contacts\n"); if (mustdeleteimpu) { + if (!dbwork) { + start_dbtransaction(); + dbwork=1; + } register_udomain("location", &_d); delete_impurecord(_d, &_r->public_identity, _r); } else { @@ -437,6 +472,17 @@ static inline void process_impurecord(impurecord_t* _r) { _r->reg_state = IMPU_UNREGISTERED; } } + + if (dbwork) { + if (ul_dbf.raw_query(ul_dbh, &commit, NULL) < 0) { + LM_ERR("transaction commit " + "failed.\n"); + } + if (ul_dbf.raw_query(ul_dbh, &autocommit_on, NULL) < 0) { + LM_ERR("could not turn " + "transaction autocommit on.\n"); + } + } } /*! diff --git a/modules/ims_usrloc_scscf/usrloc_db.c b/modules/ims_usrloc_scscf/usrloc_db.c index 2b374349f85..af8c8a18af8 100644 --- a/modules/ims_usrloc_scscf/usrloc_db.c +++ b/modules/ims_usrloc_scscf/usrloc_db.c @@ -67,12 +67,12 @@ int query_buffer_len = 0; char* impu_contact_insert_query = "INSERT INTO impu_contact (impu_id, contact_id) (SELECT I.id, C.id FROM impu I, contact C WHERE I.impu='%.*s' and C.contact='%.*s')"; int impu_contact_insert_query_len; -char* impu_contact_delete_query = "DELETE FROM impu_contact WHERE impu_id in (select impu.id from impu where impu.impu='%.*s') AND contact_id in (select contact.id from contact where contact.contact='%.*s')"; +char* impu_contact_delete_query = "DELETE impu_contact FROM impu_contact INNER JOIN impu ON impu_contact.impu_id = impu.id INNER JOIN contact ON contact.id = impu_contact.contact_id where impu.impu = '%.*s' and contact.contact = '%.*s'"; int impu_contact_delete_query_len; char* impu_subscriber_insert_query = "INSERT INTO impu_subscriber (impu_id, subscriber_id) (SELECT I.id, S.id FROM impu I, subscriber S WHERE I.impu='%.*s' and S.event='%.*s' and S.watcher_contact='%.*s' and S.presentity_uri='%.*s')"; int impu_subscriber_insert_query_len; -char* impu_subscriber_delete_query = "DELETE FROM impu_subscriber WHERE impu_id in (select impu.id from impu where impu.impu='%.*s') AND subscriber_id in (select subscriber.id from subscriber where subscriber.event='%.*s' and subscriber.watcher_contact='%.*s' and subscriber.presentity_uri='%.*s')"; +char* impu_subscriber_delete_query = "DELETE impu_subscriber FROM impu_subscriber INNER JOIN impu on impu_subscriber.impu_id=impu.id INNER JOIN subscriber on impu_subscriber.subscriber_id=subscriber.id WHERE impu.impu='%.*s' AND subscriber.event='%.*s' and subscriber.watcher_contact='%.*s' and subscriber.presentity_uri='%.*s'"; int impu_subscriber_delete_query_len;