From 77e114b28cb6630cd1e0d3c5f07e95cf460dc590 Mon Sep 17 00:00:00 2001 From: TED <135175623+iamtheted@users.noreply.github.com> Date: Mon, 4 Nov 2024 03:19:51 +0330 Subject: [PATCH] fix: added bunch of new queries It'll probably be my last commit of the night --- marzban/fa/examples/mysql-queries.md | 99 +++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/marzban/fa/examples/mysql-queries.md b/marzban/fa/examples/mysql-queries.md index 0d2bc8b..5ab09e7 100644 --- a/marzban/fa/examples/mysql-queries.md +++ b/marzban/fa/examples/mysql-queries.md @@ -23,6 +23,7 @@ title: کوئری‌ های کاربردی SQL ابتدا به پنل مدیریت دیتابیس مرزبان که به صورت پیش فرض روی پورت `8010` ران میشه لاگین کنید. در منوی سمت چپ روی `marzban` بزنید بعد بالای صفحه قسمت `SQL` و یک باکس سفید میاد که یک کد پیش فرض نوشته شده، اول آن را پاک می‌کنیم و بعد کوئری را وارد می‌کنیم و در نهایت دکمه `Go` که پایین باکس قرار دارد را می‌زنیم. ## لیست کوئری‌ های کاربردی SQL + - لیست کاربرانی که اشتراک آن‌ها در یک روز تعیین شده تمام می‌شود ```sql SELECT * FROM users @@ -33,17 +34,21 @@ WHERE expire >= UNIX_TIMESTAMP('2024-06-13 00:00:00') ::: tip نکته در واقع با این کوئری، ما لیست یوزرهایی که `13` ژوئن اشتراک آن‌ها تمام می‌شود را می‌بینیم، تاریخ اولی ملاک هست. ::: + - لیست کاربرانی که تا تاریخ مشخصی زمانشان به اتمام میرسد ```sql SELECT * FROM users WHERE expire < UNIX_TIMESTAMP('2024-03-10') and status = 'active'; ``` + ::: tip نکته فرضا `7` مارس هست توی کوئری بالا `10` مارس تعیین شده پس تمام کاربرانی که `3` روز از زمان آنها باقی مانده را خروجی میدهد. ::: + - لیست کاربرانی که کمتر از `2` گیگابایت از حجم شان باقی مانده ```sql SELECT * FROM users WHERE (data_limit - used_traffic) < (2*1024*1024*1024) and status = 'active' and data_limit IS NOT NULL; ``` + - لیست کاربرانی که `90` درصد حجم خود را مصرف کرده‌اند ```sql SELECT * FROM users @@ -51,6 +56,7 @@ WHERE used_traffic >= 0.9 * data_limit AND status = 'active' AND data_limit IS NOT NULL; ``` + - لیست حجم‌های زده شده به تفکیک هر ادمین ```sql SELECT admins.username, users.data_limit/1073741824, Count(*) @@ -58,6 +64,7 @@ FROM admins LEFT JOIN users ON users.admin_id = admins.id GROUP BY admins.username, users.data_limit ``` + - مشاهده حجم مصرفی ادمین‌ها ```sql SELECT admins.username, (SUM(users.used_traffic) + IFNULL(SUM(user_usage_logs.used_traffic_at_reset), 0)) / 1073741824 @@ -66,6 +73,7 @@ LEFT JOIN users ON users.admin_id = admins.id LEFT JOIN user_usage_logs ON user_usage_logs.user_id = users.id Group By admins.username ``` + - میزان مصرف ادمین‌ها از هر نود ```sql SELECT admins.username, nodes.name, SUM(node_user_usages.used_traffic)/1073741824 @@ -75,38 +83,63 @@ LEFT JOIN users ON node_user_usages.user_id = users.id LEFT JOIN admins ON users.admin_id = admins.id GROUP BY admins.username, nodes.name; ``` + +- مشاهده تعداد کاربران یک ادمین همراه با وضعیت‌های مختلف آن‌ها +```sql +SELECT + COUNT(*) AS total_users, + SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) AS active_users, + SUM(CASE WHEN status = 'expired' THEN 1 ELSE 0 END) AS expired_users, + SUM(CASE WHEN status = 'limited' THEN 1 ELSE 0 END) AS limited_users, + SUM(CASE WHEN TIMESTAMPDIFF(MINUTE, now(), online_at) = 0 THEN 1 ELSE 0 END) AS online_users +FROM users +WHERE admin_id = ADMIN_ID; +``` + - مشاهده اسم کلاینت کاربران به تعداد ```sql SELECT SUBSTR(sub_last_user_agent ,1,9), COUNT(*) FROM users WHERE status = 'active' GROUP By SUBSTR(sub_last_user_agent ,1,9) ORDER By SUBSTR(sub_last_user_agent ,1,9); ``` + - مشاهده کاربران آنلاین و تعداد آن‌ها ```sql SELECT username FROM users WHERE TIMESTAMPDIFF(MINUTE, now(), online_at) = 0; ``` -- لیست کاربرانی که `X` روز لینک سابسکریپشن خود را آپدیت نکردند + +- لیست کاربرانی که در `1` روز اخیر لینک سابسکریپشن خود را آپدیت کردند. +```sql +SELECT username, datediff(now(), sub_updated_at) as LastUpdate FROM users +WHERE datediff(now(), sub_updated_at) < 1 AND status = 'active' ORDER BY LastUpdate DESC; +``` + +- لیست کاربرانی که در `10` روز اخیر لینک سابسکریپشن خود را آپدیت نکردند. ```sql SELECT username, datediff(now(), sub_updated_at) as LastUpdate FROM users WHERE datediff(now(), sub_updated_at) > 10 AND status = 'active' ORDER BY LastUpdate DESC; ``` + ::: tip نکته در کوئری بالا جای عدد `10` تعداد روز دلخواه را بگذارید. ::: + - لیست کاربرانی که اینباند غیرفعال دارند ```sql SELECT users.username, proxies.id, exclude_inbounds_association.inbound_tag FROM users INNER JOIN proxies ON proxies.user_id = users.id INNER JOIN exclude_inbounds_association ON exclude_inbounds_association.proxy_id = proxies.id ORDER BY users.username; ``` + - لیست کاربرانی که پروتکل `Vmess` برای آن‌ها غیر فعال است ```sql SELECT users.username FROM users WHERE users.username not in (SELECT users.username FROM users LEFT JOIN proxies ON proxies.user_id = users.id WHERE proxies.type = 'VMESS'); ``` + ::: tip نکته در خصوص کوئری بالا اگر قصد دارید پروتکل‌های دیگر را چک کنید فقط اسم پروتکل را عوض کنید و حتما حروف بزرگ باشد. ::: @@ -119,79 +152,97 @@ WHERE proxies.type = 'VMESS'); UPDATE users SET users.admin_id = 3 WHERE users.admin_id = 6; ``` + - غیر فعال کردن تمام کاربران یک ادمین خاص ```sql UPDATE users SET users.status= 'disabled' WHERE users.admin_id = '1' and users.status= 'active' ``` + - فعال کردن تمام کاربران غیر فعال یک ادمین خاص ```sql UPDATE users SET users.status= 'active' WHERE users.admin_id = '1' and users.status= 'disabled' ``` + - اضافه کردن `1` روز به زمان کاربران همه ادمین‌ها سودو و غیر سودو ```sql UPDATE users SET expire=expire+(86400 * 1) WHERE expire IS NOT NULL ``` + - کم کردن `1` روز از زمان کاربران همه ادمین‌ها سودو و غیر سودو ```sql UPDATE users SET expire=expire-(86400 * 1) WHERE expire IS NOT NULL ``` + - اضافه کردن `1` روز به زمان کاربران یک ادمین خاص ```sql UPDATE users SET expire=expire+(86400 * 1) WHERE expire IS NOT NULL and admin_id in (100,200) ``` + - کم کردن `1` روز از زمان کاربران یک ادمین خاص ```sql UPDATE users SET expire=expire-(86400 * 1) WHERE expire IS NOT NULL and admin_id in (100,200) ``` + - اضافه کردن `20` درصد از حجم تعیین شده همه کاربران یک ادمین خاص به آن ها ```sql UPDATE users SET data_limit = data_limit + (data_limit * 20) / 100 WHERE data_limit IS NOT NULL and admin_id in (100,200) ``` + - کم کردن `20` درصد از حجم تعیین شده همه کاربران یک ادمین خاص از آن ها ```sql UPDATE users SET data_limit = data_limit - (data_limit * 20) / 100 WHERE data_limit IS NOT NULL and admin_id in (100,200) ``` + ::: tip نکته در خصوص دو اسکریپت `SQL` بالا برای تغییر درصد، عدد `20` را به عدد دلخواه تغییر دهید. دقت کنید بیست درصد از حجم تعیین شده برای هر کاربر به آن اضافه خواهد شد، برای مثال اگر حجم تعیین شده کاربری `100` گیگابایت باشد، بعد از اجرا کردن کد بالا حجم او `120` گیگابایت خواهد بود. ::: + ::: tip نکته در خصوص اسکریپت های `SQL` که برای یک ادمین خاص هستند لازم است تا آیدی ادمین در تیبل دیتابیس را وارد کنید بعد کد را ران کنید، در بعضی کدها ممکن است صرفا یوزنیم ادمین لازم باشد پس تفاوت این دو نوع کد را تشخیص دهید. همچنین در بعضی کدها برای مثال دو آیدی در پرانتز با کاما بین آن ها آمده است، اگر یک ادمین دارید صرفا آیدی یک ادمین را بگذارید و اگر بیش از یک ادمین دارید، به تعداد ادمین ها آن ها را با کاما از هم جدا کنید. ::: + - حذف کاربرانی که بیشتر از `30` روز از تاریخ انقضا آن‌ها گذشته ```sql delete from users where datediff(now(),from_unixtime(expire))> 30 ``` + ::: tip نکته در خصوص مورد بالا باید تیک `enable foreign key checks` خاموش باشد. ::: + - حذف همه کاربرانی که غیرفعال شده‌اند ```sql delete from users where status = 'disabled' ``` + - کاربرانی که پروتکل `Vless` را فعال دارند اگر `Flow` برای آن‌ها ست نشده باشه برای آن‌ها ست می‌کنه ```sql UPDATE proxies SET settings = JSON_SET(settings, '$.flow', 'xtls-rprx-vision') WHERE type = 'VLESS' AND JSON_UNQUOTE(JSON_EXTRACT(settings, '$.flow')) = ''; ``` + - فعال کردن پروتکل `Vmess` برای کاربران همه ادمین‌ها سودو و غیر سودو ```sql INSERT INTO proxies (user_id, type,  settings) SELECT id, "VMess", CONCAT("{""id"": """, CONVERT(UUID() , CHAR) , """}") FROM users; ``` + - غیرفعال کردن پروتکل `Vmess` برای کاربران همه ادمین‌ها سودو و غیر سودو ```sql DELETE FROM proxies WHERE type = "VMess" ``` + - فعال کردن پروتوکل `Vmess` برای کاربران یک ادمین خاص ```sql INSERT INTO proxies (user_id, type,  settings) SELECT id, "VMess", CONCAT("{""id"": """, CONVERT(UUID() , CHAR) , """}") FROM users inner join admins ON  users.admin_id = admins.id WHERE admins.username = "admin1"; ``` + - غیرفعال کردن پروتکل `Vmess` برای کاربران یک ادمین خاص ```sql DELETE proxies @@ -208,9 +259,11 @@ WHERE type = 'VMess' and proxies.id in (     ) AS p ); ``` + ::: tip نکته در خصوص فعال یا غیرفعال کردن پروتکل‌ها برای سایر پروتکل‌ها خودتون می‌تونین جای `VMess` قرار بدید و وارد کنید. همچنین جای `admin1` یوزنیم ادمین مورد نظر خود را قرار بدید و وارد کنید. ::: + - فعال کردن یک اینباند خاص برای کاربران همه ادمین‌ها سودو و غیر سودو ```sql DELETE FROM exclude_inbounds_association @@ -221,6 +274,7 @@ WHERE proxy_id IN ( INNER JOIN proxies ON proxies.user_id = users.id ) AND inbound_tag = 'INBOUND_NAME'; ``` + - فعال کردن یک اینباند خاص برای کاربران یک ادمین خاص ```sql DELETE FROM exclude_inbounds_association @@ -232,12 +286,14 @@ WHERE proxy_id IN ( WHERE admins.username = 'ADMIN' ) AND inbound_tag = 'INBOUND_NAME'; ``` + - غیرفعال کردن یک اینباند خاص برای کاربران همه ادمین‌ها سودو و غیر سودو ```sql INSERT INTO exclude_inbounds_association (proxy_id, inbound_tag) SELECT proxies.id, "INBOUND_NAME" FROM users INNER JOIN admins ON users.admin_id = admins.id INNER JOIN proxies ON proxies.user_id = users.id ``` + - غیرفعال کردن یک اینباند خاص برای کاربران یک ادمین خاص ```sql INSERT INTO exclude_inbounds_association (proxy_id, inbound_tag) @@ -245,16 +301,54 @@ SELECT proxies.id, "INBOUND_NAME" FROM users INNER JOIN admins ON users.admin_id = admins.id INNER JOIN proxies ON proxies.user_id = users.id Where admins.username = "ADMIN"; ``` + ::: tip نکته در کوئری‌ها بالا که در خصوص فعال و غیرفعال کردن اینباند هست لازمه که جای `INBOUND_NAME` اسم اینباند مورد نظرتون را بگذارید و فقط در کوئری‌های مربوط به یک ادمین خاص یوزنیم ادمین مورد نظرتون را جای `ADMIN` قرار بدید. ::: + ::: warning توجه در چهار کوئری‌ بالا که برای فعال یا غیرفعال کردن اینباند هست لازمه بدانید اگر به عنوان مثال پروتکل `Vless` برای کاربران فعال نباشد کوئری‌ های بالا برای فعال کردن اینباند تاثیری نخواهند داشت پس اول باید آن پروتکل به خصوص فعال باشد بعد اینباند آن پروتکل دلخواه را فعال یا غیرفعال کنید. ::: + ::: warning توجه دقت کنید اگر از اسکریپت‌های `SQL` بالا برای فعال کردن پروتکل یا اینباند استفاده ‌می‌کنید، اگر آن اینباند یا پروتکل از قبل حتی برای یک کاربر فعال باشه، تکراری ثبت میشه و باعث میشه `Xray` تمام نودهای شما مکررا ریستارت بشه لذا اگر قصد دارید پروتکل یا اینباند خاصی را برای کاربران فعال کنید، اول برای همه آن را غیرفعال کنید تا اگر از قبل برای کسی فعال بوده غیرفعال شود و سپس برای همه فعال کنید. ::: +- اگر از کوئری برای پاک کردن یوزرها استفاده کردید، پیشنهاد می‌شود که `3` کوئری زیر اجرا بشه تا پروکسی‌ها و ریست حجم‌ها و اکسکلود‌های کاربرهای حذف شده پاک شود در نتیجه دیتابیس سبک‌تر شود. + +```sql +delete from proxies where user_id not in (select id from users); +``` +```sql +delete from user_usage_logs where user_id not in (select id from users); +``` +```sql +delete from exclude_inbounds_association where proxy_id not in (select id from proxies); +``` +- اگر `exclude inbound` نداشته باشید کوئری سوم هیچ رکوردی را پاک نخواهد کرد. + +::: tip نکته +- پیشنهاد میشه جدول `node_user_usages` رو هم `empty` بزنید. + +در آخر پیشنهاد میشه بعد از انجام مراحل بالا، روی جدول‌های + +`users` + +`proxies ` + +`exclude_inbound_association` + +`user_usages_logs` + +گزینه `optimize table` رو نیز بزنید. + +- این بخش را در بالای صفحه قسمت `Operations` بعد بخش `Table maintenance` می‌توانید پیدا کنید. +::: + +::: tip نکته +همچنین حتما بصورت دوره‌ای کاربرهای غیرفعال را پاک کنید چراکه در سرعت پنل و باگ‌های ناشناخته از قبیل `dead lock` تاثیر خواهد داشت. +::: + ## ایونت‌ های کاربردی SQL ایونت‌ها برای سکریپت‌های `SQL` که می‌خوایم در زمان خاصی اجرا بشن کاربرد دارن و فقط برای کوئری‌هایی که در دیتابیس تغییری ایجاد می‌کنن، میشه ایونت قرار داد و برای کوئری‌هایی که خروجی میدن نمیشه این کار را انجام داد. @@ -264,10 +358,12 @@ CREATE EVENT Clear_NodeUserUsages ON SCHEDULE EVERY 1 WEEK STARTS '2024-05-03 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO TRUNCATE node_user_usages ``` + - ایونت روزانه برای ست کردن `Flow` چنانچه فراموش کنید برای کاربر بگذارید ```sql CREATE DEFINER=`root`@`%` EVENT `SetFlow` ON SCHEDULE EVERY 1 DAY STARTS '2024-06-01 01:00:00' ON COMPLETION NOT PRESERVE ENABLE DO UPDATE proxies SET settings = JSON_SET(settings, '$.flow', 'xtls-rprx-vision') WHERE type = 'VLESS' AND JSON_UNQUOTE(JSON_EXTRACT(settings, '$.flow')) = ''; ``` + ::: tip نکته چطور یک ایونت را خاموش کنیم؟ بعد از فعال کردن اون بالا دکمه `Drop` را بزنین غیرفعال می‌شود ، اما توجه داشته باشید اگر دکمه `On` و `Off` کنید کلیه `Event` ها غیرفعال می‌شوند. ::: @@ -290,6 +386,7 @@ CREATE TRIGGER admin_delete BEFORE DELETE ON users FOR EACH ROW IF OLD.admin_id END IF ``` برای غیرفعال کردن تریگر‌ها مثل ایونت‌ها دکمه `Drop` را بزنید غیرفعال می‌شود. + ::: tip نکته دقت کنین داخل پرانتز برای مثال سه تا آیدی ذکر شده ، این بستگی به شما داره که بخواید روی چندتا از ادمین‌هاتون این تریگر را اعمال کنید، آیدی ادمین مورد نظرتون را از تیبل‌های دیتابیس پیدا کرده و جایگزین کنید. :::