Browse Source

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

jaybeepee 9 years ago
parent
commit
29dcaf3a78
2 changed files with 48 additions and 2 deletions
  1. 46 0
      modules/ims_usrloc_scscf/impurecord.c
  2. 2 2
      modules/ims_usrloc_scscf/usrloc_db.c

+ 46 - 0
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");
+        }
+    }
 }
 
 /*!

+ 2 - 2
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;