I will try to give as much information as possible here. Although the solution will be wonderful, I just want to give recommendations on how to solve this problem. How to view more useful log files, etc. Since I am new to server maintenance. Any advice is appreciated.
Here is what happens in chronological order:
- I launch two drops with the digital ocean (Ubuntu 14.04 VPS)
- Drop # 1 working on django, nginx, gunicorn
- Drop # 2 performing postgr
- Everything works fine for a month, and suddenly a drop of postgres 100% CPU usage
- You can see the htop log when this happens. I added a screenshot
- Another screenshot is nginx error.log, you can see this problem started at 15:56:14, where I highlighted a red frame.
- sudo poweroff drops Postgres and restarting it does not fix the problem
- Restoring drops of postgres to my last backup (20 hours ago) solves the problem, but it continues to repeat. This is the 7th time in 2 days.
I will continue to do research and give more information. Meanwhile, any opinions are welcome.
Thanks.

May 20, 2016 Patch
- Slow request logging is enabled on the Postgres server, as recommended by e4c5
- After 6 hours, the server freezes (100% CPU utilization) again at 8:07 in the morning. I have added all the related screenshots.
- The browser displays error 502 when trying to access the site during blocking
sudo service restart postgresql (and gunicorn, nginx on django server) does NOT fix freeze ( I think this is a very interesting point )- However restore the Postgres server to my previous backup (now 2 days) does the freeze fix
- Postgres log error message Failed to send data to client: Broken Pipe
- Nginx log error message is a simple django-rest framework
api that return only 20 elements (each with some foreign key data request)
Update No. 2 May 20, 2016 When freezing occurs, I tried to do the following in chronological order (turn off all and turn them one by one)
sudo service stop postgresql CPU usage drops to 0-10%sudo service stop gunicorn β cpu usage stays at 0-10%sudo service stop nginx cpu usage stays at 0-10%sudo service restart postgresql CPU usage remains at 0-10%sudo service restart gunicorn β cpu usage stays at 0-10%sudo service restart nginx β Using cpu has grown to 100% and remains to eat
So, is this not about server loading or a long request time?
This is very confusing, because if I restored the database to my last backup (2 days ago), everything returns to the network without even touching the nginx / gunicorn / django server ...
Update June 8, 2016. I turned on slow query logging. Set it for log requests that are longer than 1000 ms.
I have received this request in the journal many times.
SELECT "products_product"."id", "products_product"."seller_id", "products_product"."priority", "products_product"."media", "products_product"."active", "products_product"."title", "products_product"."slug", "products_product"."description", "products_product"."price", "products_product"."sale_active", "products_product"."sale_price", "products_product"."timestamp", "products_product"."updated", "products_product"."draft", "products_product"."hitcount", "products_product"."finished", "products_product"."is_marang_offline", "products_product"."is_seller_beta_program", COUNT("products_video"."id") AS "num_video" FROM "products_product" LEFT OUTER JOIN "products_video" ON ( "products_product"."id" = "products_video"."product_id" ) WHERE ("products_product"."draft" = false AND "products_product"."finished" = true) GROUP BY "products_product"."id", "products_product"."seller_id", "products_product"."priority", "products_product"."media", "products_product"."active", "products_product"."title", "products_product"."slug", "products_product"."description", "products_product"."price", "products_product"."sale_active", "products_product"."sale_price", "products_product"."timestamp", "products_product"."updated", "products_product"."draft", "products_product"."hitcount", "products_product"."finished", "products_product"."is_marang_offline", "products_product"."is_seller_beta_program" HAVING COUNT("products_video"."id") >= 8 ORDER BY "products_product"."priority" DESC, "products_product"."hitcount" DESC LIMIT 100
I know such an ugly request (generated by django aggregation). In English, this query simply means "give me a list of products that contain more than 8 videos."
And here is the EXPLAIN output of this request:
QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Limit (cost=351.90..358.40 rows=100 width=933) -> GroupAggregate (cost=351.90..364.06 rows=187 width=933) Filter: (count(products_video.id) >= 8) -> Sort (cost=351.90..352.37 rows=187 width=933) Sort Key: products_product.priority, products_product.hitcount, products_product.id, products_product.seller_id, products_product.media, products_product.active, products_product.title, products_product.slug, products_product.description, products_product.price, products_product.sale_active, products_product.sale_price, products_product."timestamp", products_product.updated, products_product.draft, products_product.finished, products_product.is_marang_offline, products_product.is_seller_beta_program -> Hash Right Join (cost=88.79..344.84 rows=187 width=933) Hash Cond: (products_video.product_id = products_product.id) -> Seq Scan on products_video (cost=0.00..245.41 rows=2341 width=8) -> Hash (cost=88.26..88.26 rows=42 width=929) -> Seq Scan on products_product (cost=0.00..88.26 rows=42 width=929) Filter: ((NOT draft) AND finished)
(11 lines)
--- Update June 8, 2016 # 2 --- Since many people offer many offers. Therefore, I will try to apply the corrections one by one and periodically report back.
@ e4c5 Here you need some info:
You can think of my site as an Udemy online course. There is a "Product" (course). Each product contains several videos. Users can comment on both the product page and all videos.
In many cases, I will need to request a list of product orders by the number of TOTAL comments received (the sum of the comments and comments for each video of this product)
A django request that matches the EXPLAIN output above:
all_products_exclude_draft = Product.objects.all().filter(draft=False) products_that_contain_more_than_8_videos = all_products_exclude_draft.annotate(num_video=Count('video')).filter(finished=True, num_video__gte=8).order_by('timestamp')[:30]
I just noticed that I (or some other developer on my team) got into the database twice with these two python lines.
Here are the django models for the product and video:
from django_model_changes import ChangesMixin class Product(ChangesMixin, models.Model): class Meta: ordering = ['-priority', '-hitcount'] seller = models.ForeignKey(SellerAccount) priority = models.PositiveSmallIntegerField(default=1) media = models.ImageField(blank=True, null=True, upload_to=download_media_location, default=settings.MEDIA_ROOT + '/images/default_icon.png', storage=FileSystemStorage(location=settings.MEDIA_ROOT)) active = models.BooleanField(default=True) title = models.CharField(max_length=500) slug = models.SlugField(max_length=200, blank=True, unique=True) description = models.TextField() product_coin_price = models.IntegerField(default=0) sale_active = models.BooleanField(default=False) sale_price = models.IntegerField(default=0, null=True, blank=True)
And here is the index of the product table and the video that I received from the team:
my_database_name=
Note: this is photoshop, as well as some other models. 
--- Update June 8, 2016 No. 3 --- @Jerzyk As you suspected. After I checked all my code again, I found that I really did a βslicing in memoryβ: I tried to shuffle the first 10 results by doing the following:
def get_queryset(self): all_product_list = Product.objects.all().filter(draft=False).annotate( num_video=Count( Case( When( video__draft=False, then=1, ) ) ) ).order_by('-priority', '-num_video', '-hitcount') the_first_10_products = list(all_product_list[:10]) the_11th_product_onwards = list(all_product_list[10:]) random.shuffle(copy) finalList = the_first_10_products + the_11th_product_onwards
Note: in the code above, I need to count the number of videos that are not in draft status.
So this will be one of the things I need to fix. Thank you > _ & L;
--- Below are the corresponding screenshots ---
Postgres freeze log (log_min_duration = 500 milliseconds) 
Postgres Magazine (based on the screenshot above) 
Nginx error.log for the same time period 
DigitalOcean CPU usage schedule just before freezing 
DigitalOcean processor usage chart immediately after freezing 